CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-6XX4-9WP6-65P7

GHSA-6XX4-9WP6-65P7: Arbitrary Local File Disclosure via UNIX Symlink Following in skilo

Amit Schendel
Amit Schendel
Senior Security Researcher

Jul 29, 2026·5 min read·14 visits

Executive Summary (TL;DR)

A UNIX symbolic link following vulnerability in skilo's installation routine allows attackers to exfiltrate arbitrary local files readable by the target user.

A local file disclosure vulnerability exists in the Rust-based package skilo. When copying files during skill installation, the application recursively traverses directories but dereferences symbolic links, resulting in unauthorized local file reading.

Vulnerability Overview

The Rust-based package skilo is designed to install custom skills from remote and local sources using the skilo add command. This feature clones or copies files from a source directory into the user's local installation directory. During the installation process, the application recursively walks the source folder structure and copies individual files to their target destinations.\n\nThe copy operations are handled by a recursive helper function that fails to validate the nature of files before processing. Specifically, the system does not safely handle UNIX symbolic links (symlinks) encountered within the source repository. When a symlink is encountered, the tool retrieves the file contents of the resolved target path rather than preserving or rejecting the link itself.\n\nThis behavior introduces a local file disclosure vulnerability. An attacker can host a crafted skill directory containing a symbolic link pointing to a sensitive file on the victim's host filesystem, such as private keys or local configuration files. When the victim executes the installation command, the tool copies the contents of the target file into the newly installed skill directory, allowing subsequent unauthorized access.

Root Cause Analysis

The core flaw lies in a mismatch between how file metadata is queried and how the file is copied during recursive traversal. In src/commands/add.rs, the recursive helper function copy_dir_all reads directory entries using std::fs::read_dir(src). For each entry, it queries the file type using std::fs::DirEntry::file_type().\n\nIn the Rust standard library, DirEntry::file_type() retrieves metadata directly from the directory entry itself without following symbolic links. Consequently, if an entry is a symbolic link, ty.is_dir() returns false. This causes execution to fall through to the else block, which assumes the entry is a regular file.\n\nThe application then attempts to copy the entry using std::fs::copy(&src_path, &dst_path). Unlike DirEntry::file_type(), std::fs::copy() traverses and dereferences symbolic links. It reads the contents of the file pointed to by the symbolic link and writes them to a new, regular file at the destination path. This creates a regular file containing the sensitive target data inside the installation directory.

Code Analysis

rust\n// Vulnerable Implementation (v0.5.0 - v0.11.0)\nfn copy_dir_all(src: &Path, dst: &Path) -> Result<(), SkiloError> {\n fs::create_dir_all(dst)?;&\n for entry in fs::read_dir(src)? {\n let entry = entry?;\n let ty = entry.file_type()?; // Queries metadata of the entry itself\n let src_path = entry.path();\n let dst_path = dst.join(entry.file_name());\n\n if ty.is_dir() {\n copy_dir_all(&src_path, &dst_path)?;\n } else {\n // If entry is a symlink, ty.is_dir() is false.\n // fs::copy dereferences the symlink and reads the external target file.\n fs::copy(&src_path, &dst_path)?;\n }\n }\n Ok(())\n}\n\n\nThe patch implemented in version 0.11.1 resolves this flaw by explicitly invoking ty.is_symlink(). If a symbolic link is detected, the function immediately terminates execution and returns a custom error, preventing the file from being copied.\n\nrust\n// Patched Implementation (v0.11.1)\nfn copy_dir_all(src: &Path, dst: &Path) -> Result<(), SkiloError> {\n fs::create_dir_all(dst)?;&\n for entry in fs::read_dir(src)? {\n let entry = entry?;\n let ty = entry.file_type()?;\n let src_path = entry.path();\n let dst_path = dst.join(entry.file_name());\n\n if ty.is_symlink() {\n // Refuse symlinks explicitly to prevent dereference leakage\n return Err(SkiloError::SymlinkInSkill {\n path: src_path.display().to_string(),\n });\n } else if ty.is_dir() {\n copy_dir_all(&src_path, &dst_path)?;\n } else {\n fs::copy(&src_path, &dst_path)?;\n }\n }\n Ok(())\n}\n

Exploitation Methodology

An attacker can exploit this vulnerability by publishing a malicious skill containing a symbolic link. The link is crafted to point to a standard file path containing sensitive data, such as /home/user/.ssh/id_rsa or /home/user/.aws/credentials.\n\nbash\n# Attacker directory setup\nmkdir malicious-skill\ncd malicious-skill\n# Create symlink pointing to user's SSH private key\nln -s /home/user/.ssh/id_rsa target_data.txt\n\n\nThe attacker hosts the repository on a public platform and induces the target user to run the installation command. When the user executes the command, the application retrieves the remote repository and executes the file copy routine.\n\nbash\nskilo add github.com/attacker/malicious-skill\n\n\nDuring the copy phase, the copy_dir_all function processes target_data.txt. Because the link is dereferenced during the copy operation, the victim's private key contents are copied into ~/.local/share/skilo/skills/malicious-skill/target_data.txt. The attacker can retrieve these contents if the application synchronizes skill directories to external backends or exposes skill files to the agent workspace.

Impact Assessment

The vulnerability has a CVSS v3.1 score of 6.5, reflecting medium severity. The impact is restricted to local file disclosure. The attacker cannot modify target files or execute arbitrary commands directly through this vector, resulting in zero integrity and availability impact.\n\nThe confidentiality impact is high because the vulnerability allows the exfiltration of any local files readable by the user executing the skilo command. This includes SSH private keys, cloud configuration tokens, database credentials, and system environment variables.\n\nThe attack vector is classified as network because the exploit payload is delivered via a remote Git repository. The user must be tricked into installing the malicious skill, which requires active user interaction. The attack complexity is low as the exploit relies on standard UNIX filesystem mechanisms.

Remediation and Mitigation

Users must upgrade skilo to version 0.11.1 or higher to eliminate the vulnerability. This patch introduces validation that rejects any installation source containing symbolic links. The application fails closed and refuses to copy files if a symlink is encountered.\n\nIf immediate upgrade is not possible, users must inspect remote repositories before executing the installation command. The presence of symbolic links in a directory can be verified by executing the find command on the cloned repository.\n\nbash\nfind /path/to/skill/repository -type l\n\n\nAdditionally, executing the application under a dedicated, low-privileged user account limits the scope of accessible files. Isolating the installation environment using containers or sandbox utilities prevents access to sensitive host directories like ~/.ssh or ~/.aws.

Official Patches

manuelmauroOfficial patch implementing symlink validation
manuelmauroPull Request #11 containing code review and fix tests

Fix Analysis (1)

Technical Appendix

CVSS Score
6.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N
EPSS Probability
0.04%
Top 100% most exploited

Affected Systems

skilo

Affected Versions Detail

Product
Affected Versions
Fixed Version
skilo
manuelmauro
>= 0.5.0, < 0.11.10.11.1
AttributeDetail
CWE IDCWE-59
Attack VectorNetwork
CVSS Score6.5
EPSS Score0.00045
ImpactConfidentiality (High)
Exploit Statuspoc
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1204.001User Execution: Malicious Link
Execution
T1552Unsecured Credentials
Credential Access
CWE-59
Improper Link Resolution Before File Access ('Link Following')

Improper Link Resolution Before File Access ('Link Following')

Known Exploits & Detection

GitHub Advisory DatabaseAdvisory page detailing the local file disclosure and official regression test cases serving as a proof of concept.

Vulnerability Timeline

Pull Request #11 merged and fix commit applied
2026-06-08
GHSA-6XX4-9WP6-65P7 published
2026-07-28

References & Sources

  • [1]GHSA-6XX4-9WP6-65P7 Advisory
  • [2]Vendor Security Advisory

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 7 hours ago•CVE-2026-107844
5.3

CVE-2026-107844: Path Traversal Vulnerability in Contao ImagesController

A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.

Amit Schendel
Amit Schendel
8 views•5 min read
•about 9 hours ago•CVE-2026-107848
3.5

CVE-2026-107848: Cross-Site Request Forgery (CSRF) in Contao Backend Actions via GET Requests

Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.

Amit Schendel
Amit Schendel
7 views•5 min read
•about 10 hours ago•CVE-2026-107843
5.3

CVE-2026-107843: Unthrottled Activation Email Resend and Account Enumeration in Contao CMS

Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.

Amit Schendel
Amit Schendel
8 views•4 min read
•about 11 hours ago•CVE-2026-107842
5.3

CVE-2026-107842: Information Disclosure via Stale Indexing in Contao Search Module

An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.

Amit Schendel
Amit Schendel
9 views•4 min read
•about 12 hours ago•GHSA-G38J-7V97-X298
6.5

GHSA-G38J-7V97-X298: Missing Authorization Check in Vikunja CalDAV Task Relation Creation

In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.

Alon Barad
Alon Barad
10 views•5 min read
•about 13 hours ago•GHSA-3HC7-R24J-RPWC
6.8

GHSA-3hc7-r24j-rpwc: Cross-Project Task Disclosure via Subtask Expansion in Vikunja

A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.

Alon Barad
Alon Barad
9 views•5 min read