GHSA-wx3m-whqv-xv47 - skillctl path and symlink traversal
skillctl versions before 0.1.2 could follow symlinks inside skill folders
and trust unsafe path fields in .skills.toml. A malicious skill library or PR
could exfiltrate local files by copying symlink targets into a project and then
publishing them, or delete writable directories outside the intended project or
library root through unsafe destination, source_path, detect --target, or
fork-name handling.
For teams that treat skills as reusable agent instructions, this is a supply-chain boundary issue. The right PR upgrades the tool, rejects unsafe library metadata, quarantines untrusted skill imports, and adds path-safety tests around destructive copy, pull, push, detect, and fork operations.
When to use it
Use this recipe when a repository installs, wraps, documents, or automates
skillctl, skill libraries, .skills.toml, reusable agent skills, marketplace
sync jobs, or onboarding flows that copy skills into developer or CI projects.
It is most important when contributors, customers, plugins, forks, or external
marketplaces can provide skill folders or metadata.
Use it to upgrade skillctl, quarantine untrusted skill libraries, and harden
path handling around copy, pull, push, detect, fork, replacement, and publishing
flows. Do not use it to run untrusted skill operations on a host with secrets.
Inputs
- Cargo manifests and locks, install scripts, CI images, Dockerfiles, release
jobs, developer setup docs, agent onboarding docs, marketplace sync jobs,
.skills.tomlfiles, skill libraries, generated SBOMs, and runbooks. - Skill-library metadata fields including
destination,source_path,detect --target, custom target prompts, fork names, publish targets, symlinks, folder replacement behavior, and destructive copy/delete paths. - Trust boundaries for skill sources: PR-submitted libraries, customer skill packs, plugins, marketplace content, forks, vendored skills, and internal curated libraries.
- Operator authority: home-directory secrets, SSH keys, cloud credentials, package tokens, source checkouts, private prompts, CI workspaces, writable project roots, and library roots.
- Existing path-safety controls, safe-join helpers, symlink policy, quarantine process, review gates, audit logs, and disposable-workspace setup.
Affected versions
- Vulnerable package:
skillctl <0.1.2 - Fixed package:
skillctl 0.1.2+ - Affected package manager: Cargo
- Affected inputs:
.skills.tomldestinationandsource_path, symlinks inside skill folders,detect --target, custom target prompts, and fork names equal to.or.. - Affected operations: skill copy, pull, push, detect, folder replacement, publishing, and fork rename flows
Indicator-of-exposure
- The repository installs, pins, vendors, or documents
skillctl <0.1.2. - CI, developer setup, release automation, or agent onboarding runs
skillctlagainst skill libraries submitted by contributors, customers, plugins, forks, or external marketplaces. .skills.tomlfiles are accepted through PRs or copied from untrusted skill libraries without review.- Skill folders may contain symlinks, absolute paths,
..traversal, Windows drive prefixes, UNC-style paths, or fork names that affect filesystem joins. - The operator running
skillctlhas access to home-directory secrets, cloud credentials, SSH keys, source checkouts, private package tokens, CI workspaces, or writable project/library directories.
Quick checks:
rg -n "skillctl|\\.skills\\.toml|source_path|destination|detect --target|fork|skills library|skill library" .
cargo install --list | rg -i "skillctl"
cargo tree -i skillctl
rg -n "skillctl|\\.skills\\.toml|source_path|destination|detect --target" Cargo.toml Cargo.lock Dockerfile* .github scripts docs content . 2>/dev/null
Windows:
rg -n "skillctl|\\.skills\\.toml|source_path|destination|detect --target|fork|skills library|skill library" .
cargo install --list | rg -i "skillctl"
cargo tree -i skillctl
rg -n "skillctl|\\.skills\\.toml|source_path|destination|detect --target" Cargo.toml Cargo.lock Dockerfile* .github scripts docs content .
Do not run skillctl pull, push, detect, or copy operations on untrusted
skill libraries from a workstation or CI runner that has secrets mounted.
Remediation strategy
- Upgrade every controlled
skillctlinstall, lockfile, bootstrap script, CI image, developer setup guide, release container, and SBOM entry to0.1.2+. - Quarantine or re-review skill libraries imported while
skillctl <0.1.2was in use. Look for unexpected symlinks, absolute paths, traversal components, unsafe.skills.tomlpath fields, and surprising published files. - Reject symlinks inside skill folders before copying or publishing. Treat both top-level symlinks and descendant symlinks as unsafe for untrusted libraries.
- Validate all user-controlled relative paths lexically before filesystem
operations. Reject absolute paths,
.., Windows prefixes, UNC-style inputs, empty path components where unsafe, and fork names.or... - Use a safe-join helper at destructive call sites and keep delete/replace operations confined under the expected project or library root.
- Run skill tooling with least privilege: clean workspace, no home-directory secrets, no cloud metadata access, narrow write permissions, and read-only mounts where possible.
The prompt
You are remediating GHSA-wx3m-whqv-xv47, a `skillctl` path traversal and
symlink-follow issue that can disclose local files or delete writable
directories when untrusted skill libraries or `.skills.toml` metadata are
processed. Produce exactly one output:
- A reviewer-ready PR/change request that upgrades skillctl, rejects unsafe
skill metadata and symlinks, adds path-safety regression coverage, refreshes
generated artifacts, and documents operator cleanup, or
- TRIAGE.md if this repository does not control affected skillctl usage or
cannot safely patch the skill-library workflow.
## Rules
- Scope only GHSA-wx3m-whqv-xv47 and directly related skillctl path, symlink,
copy, pull, push, detect, fork, and publishing controls.
- Treat home directories, SSH keys, cloud credentials, package tokens, source
checkouts, CI secrets, customer skill content, private prompts, and published
skill packages as sensitive.
- Do not run untrusted `skillctl pull`, `push`, `detect`, copy, rename, or
delete flows on a host or CI runner that has secrets mounted.
- Do not print secrets, symlink target contents, private skill bodies, token
files, absolute home paths, or CI environment values into logs or commits.
- Do not remove skill provenance checks, review gates, quarantine, audit logs,
or path validation to make the alert disappear.
- Do not auto-merge.
## Steps
1. Inventory all `skillctl` usage controlled by this repository: Cargo
manifests and locks, install scripts, CI images, Dockerfiles, release jobs,
developer setup docs, agent onboarding docs, marketplace sync jobs,
`.skills.toml` files, skill libraries, generated SBOMs, and runbooks.
2. Determine every resolved `skillctl` version. A target is vulnerable if it
resolves to `<0.1.2`.
3. Search for untrusted skill-library paths and metadata: `source_path`,
`destination`, `detect --target`, custom target prompts, fork names, publish
workflows, pull/push automation, symlink support, folder replacement, and
destructive copy/delete operations.
4. If the repository does not install or run `skillctl`, stop with `TRIAGE.md`
listing checked files, known owners, and the required fixed version
`0.1.2+`.
5. Upgrade every controlled install, lockfile, setup script, CI image, and docs
to `skillctl 0.1.2+`. Refresh lockfiles, image digests, generated reports,
SBOMs, and developer instructions.
6. If this repository owns a fork, wrapper, or adjacent skill-library tooling,
add or verify fail-closed path safety:
- reject symlinks at every skill-copy boundary;
- reject absolute paths and `..` components in `.skills.toml`;
- reject Windows prefixes, UNC paths, empty unsafe components, and fork names
`.` or `..`;
- run every destructive path through a safe-join helper;
- confine deletes, renames, copies, and replacements under the project or
library root;
- avoid canonicalization patterns that create time-of-check/time-of-use
windows around attacker-controlled paths.
7. Add safe regression coverage:
- dependency policy rejects `skillctl <0.1.2`;
- symlinks inside skill folders are rejected before copy or publish;
- `destination`, `source_path`, and `detect --target` reject absolute paths,
traversal, and Windows-prefix paths;
- fork names `.` and `..` are rejected;
- destructive operations cannot escape a temporary test root;
- logs and fixtures do not contain real secrets or private skill content.
8. Harden operational usage:
- run imports in disposable workspaces;
- mount only the skill library and project paths needed for the run;
- keep home directories, SSH keys, cloud credentials, package tokens, and
source-control credentials out of the skillctl process environment;
- require review for `.skills.toml` changes and new symlinks;
- quarantine external skill libraries before publishing.
9. Add a PR body section named `GHSA-wx3m skillctl operator actions` that
states:
- skillctl versions before and after;
- where pull, push, detect, copy, publish, and fork flows run;
- whether untrusted skill libraries or PR-submitted `.skills.toml` files were
processed while vulnerable;
- whether any published skill packages, local projects, or library roots need
review for unexpected files or deletions;
- whether tokens, SSH keys, cloud credentials, or private prompts require
rotation because they were reachable by the operator process;
- which validation commands passed.
10. Run available validation: Cargo checks, dependency scan, lockfile
integrity, path-safety unit tests, fixture tests, CI image build, SBOM
refresh, docs link checks, and non-secret smoke checks in a disposable
workspace.
11. Use PR title:
`fix(sec): remediate GHSA-wx3m in skillctl`
## Stop conditions
- No affected skillctl install, wrapper, fork, CI image, setup script, or skill
workflow is controlled by this repository.
- Skill-library tooling is owned by another team or vendor; name the owner and
required version in `TRIAGE.md`.
- A fixed skillctl version cannot be consumed without a broader skill workflow
migration.
- Verification would require running untrusted skill operations on a secret-
bearing host, deleting real directories, copying symlink targets, or
publishing private skill content.
- Validation fails for unrelated pre-existing reasons; document those failures
instead of broadening scope.
Verification - what the reviewer looks for
- No controlled Cargo lock, setup script, CI image, docs page, SBOM, or
generated report resolves
skillctl <0.1.2. - Skill copy/publish flows reject symlinks inside skill folders before reading target contents.
.skills.tomlpath fields,detect --target, custom target prompts, and fork names reject absolute paths, traversal, Windows prefixes, and./..escapes.- Destructive copy, rename, delete, and replacement operations are confined to a temporary test root in regression tests.
- Operator notes cover quarantine, unexpected published files, local deletion review, and credential rotation criteria.
Watch for
- Updating a local
cargo installinstruction while CI images or bootstrap scripts still install the affected version. - Running
skillctlfrom an operator home directory with SSH keys, cloud credentials, or package tokens mounted. - Validating path safety with string-prefix checks that accept Windows prefixes,
UNC paths, symlinks, or
..after normalization. - Reviewing only
.skills.tomlwhile symlinks inside skill folders remain allowed. - Publishing skill libraries before checking whether vulnerable runs copied unexpected local files into the project.
Output contract
Return one of:
- A reviewer-ready PR/change request that upgrades every controlled
skillctlusage to0.1.2+, refreshes lockfiles/images/SBOMs, rejects unsafe skill paths and symlinks, quarantines external skill libraries, adds path-safety regression coverage, hardens disposable-workspace execution, and documents operator cleanup. TRIAGE.mdwhen no controlledskillctlinstall, wrapper, CI image, setup script, skill workflow, generated artifact, or skill-library publishing path exists.
The output must list skillctl versions before and after, which pull, push,
detect, copy, publish, and fork flows run, whether untrusted skill libraries or
PR-submitted .skills.toml files were processed while vulnerable, validation
commands, quarantine owners, unexpected-file/deletion review steps, and any
tokens or private prompts that require rotation. It must not copy symlink target
contents, delete real directories, publish private skills, print secrets, or
execute untrusted skill workflows on a secret-bearing host.
Related recipes
- Source-code supply chain build integrity audit
- Compromised package cache quarantine
- Agent session kill rules
References
- GitHub Advisory Database: https://github.com/advisories/GHSA-wx3m-whqv-xv47
- skillctl 0.1.2 release: https://github.com/umanio-agency/skillctl/releases/tag/v0.1.2
- Patch commit: https://github.com/umanio-agency/skillctl/commit/827fff5