GHSA-74p7-6h78-gw8p: skillctl Denial of Service Vulnerability
HIGHGHSA-74p7-6h78-gw8p is a HIGH denial of service vulnerability (CWE-400: Uncontrolled Resource Consumption) affecting skillctl libraries in the crates.io ecosystem. The issue involves argument injection, path traversal in --dest, fifo/device dos, hardlink exfiltration, and commit-trailer forgery. Remediation is available by upgrading affected packages to version 0.1.3.
GHSA-74p7-6h78-gw8p at a Glance
How to Fix GHSA-74p7-6h78-gw8p
To remediate this vulnerability, upgrade all affected skillctl dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
Upgrade skillctl to 0.1.3
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
inspect dependencies for skillctl
How to Check if You Are Affected
To determine whether your application is affected by GHSA-74p7-6h78-gw8p, inspect your project dependencies for skillctl:
inspect dependencies for skillctl
Analyze the terminal output to locate any version of skillctl in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.1.3), your application is affected.
Note: Verify declared build manifests and deployed runtime container environments.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-400: Uncontrolled Resource Consumption, where the product does not properly control the allocation and maintenance of a limited resource. In skillctl, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
GHSA-74p7-6h78-gw8p Affected skillctl Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
skillctl
|
crates.io |
< 0.1.3
|
0.1.3
|
References
Frequently Asked Questions
What is GHSA-74p7-6h78-gw8p?
Which skillctl versions are affected?
What version fixes GHSA-74p7-6h78-gw8p?
Is skillctl affected?
What CWE is associated with GHSA-74p7-6h78-gw8p?
How can I check crates.io dependencies for GHSA-74p7-6h78-gw8p?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-74p7-6h78-gw8p",
"modified" : "2026-06-22T22:45:16Z",
"published" : "2026-06-22T22:45:16Z",
"aliases" : [ ],
"summary" : "skillctl: argument injection, path traversal in --dest, FIFO/device DoS, hardlink exfiltration, and commit-trailer forgery",
"details" : "## Impact\n\nFollowing the path-safety patches in [GHSA-wx3m-whqv-xv47](https://github.com/umanio-agency/skillctl/security/advisories/GHSA-wx3m-whqv-xv47) (v0.1.2), a comprehensive multi-angle audit surfaced five further vulnerabilities, now patched in v0.1.3:\n\n1. **`source_sha` argument injection in `git ls-tree` (CRITICAL).** `InstalledSkill.source_sha` deserialized from `.skills.toml` (committed, PR-mergeable) flowed unvalidated into `git ls-tree -r -z <refspec> -- <path>`. Because the refspec sits before `--`, an attacker who slipped a malicious `.skills.toml` into a PR could set `source_sha = \"--name-only\"` / `--abbrev=0` / `--output=…` and corrupt the diff classifier (which drives `pull` / `push` destructive decisions), or forge a divergence state to trick `push --on-divergence overwrite` into clobbering the wrong content.\n2. **FIFO / device / socket denial-of-service in `copy_dir_all` (CRITICAL).** The file-type branch only checked `is_dir()` / `is_symlink()`; a FIFO inside a skill folder fell through to `fs::copy`, which blocks indefinitely waiting for a writer. A character device like `/dev/zero` would read until OOM. Reachable on `skillctl add` against any adversarial library.\n3. **`add --dest` arbitrary-directory wipe in agent mode (HIGH).** `--dest` accepted absolute paths and `..` traversal without validation, so a single invocation `skillctl add --dest /Users/victim/.ssh --on-conflict overwrite --skill <maliciously-named>` would `remove_dir_all` arbitrary directories — no `.skills.toml` round-trip required. Reachable in any non-interactive / agent-driven workflow where flag values may be attacker-supplied.\n4. **Commit-message trailer forgery via skill names (HIGH).** Skill names were spliced verbatim into `git commit -m \"update skill: <name>\"` and into the `commit.message` field of `--json` output. A skill named `foo\\nCo-Authored-By: evil@x` produced a forged commit trailer that downstream tooling (Linear, GitHub commit-bot, release-notes scrapers) treats as real authorship metadata.\n5. **Hardlink exfiltration via the round-trip (HIGH).** `fs::symlink_metadata` reports a regular file for hardlinks (shared inode), and `fs::copy` reads the target content. An untrusted agent writing `<project>/my-skill/data` as a hardlink to `~/.ssh/id_rsa` would have shipped the SSH key content to the (possibly public) library on the next `skillctl push` or `detect`.\n\n## Patches\n\nFixed in [v0.1.3](https://github.com/umanio-agency/skillctl/releases/tag/v0.1.3):\n\n- `InstalledSkill::validate` rejects any `source_sha` that isn't 40–64 hex characters.\n- `fs_util::copy_dir_all` only allows regular files and directories; FIFO / socket / device / other special files are rejected with `AppError::Config`.\n- `commands::add::resolve_destination` rejects `..` unconditionally and rejects absolute paths in non-interactive / `--json` mode.\n- New `src/sanitize.rs` module: `validate_identifier` (strict, no control bytes / newlines / ESC, used for skill `name` + individual `tags`) and `validate_message_safe` (lenient, allows `\\n` + `\\t`, rejects `\\r` + DEL + C0/C1 controls, used for `description` and `--message`). Wired at the `skill::discover` and `read_tags` boundaries so poisoned skills are dropped silently and poisoned descriptions/tags are stripped from otherwise-valid skills.\n- `fs_util::copy_dir_all` checks `metadata.nlink() > 1` on regular files (Unix) and refuses hardlinked content.\n\nAll checks are lexical or single-syscall (`symlink_metadata`, `metadata`). No `canonicalize`, no TOCTOU windows. 23 new unit + integration tests cover each rejection class; `cargo test`: 95 pass; clippy clean; `cargo audit` clean.\n\n## Workarounds\n\nUpgrade to v0.1.3. Pre-patch mitigations are awkward but possible:\n- Audit every `.skills.toml` `source_sha` field before running `skillctl pull` / `push` / `detect`.\n- Audit library content for FIFO / device files and hardlinks before running `skillctl add`.\n- Never invoke `skillctl add` with attacker-controllable `--dest` values in agent / CI contexts.\n- Never use `--message` with attacker-controlled content.\n\n## Credit\n\nThe findings were surfaced by a maintainer-led multi-angle audit (6 parallel sub-agents, one per threat-model dimension) following the firebaguette audit that motivated v0.1.2. The methodology (cross-agent convergence to identify the most exploitable items) is documented in the project's internal decisions log; the strongest signal was the four-of-six independent convergence on the `source_sha` vector.\n\n## Resources\n\n- Fix commit: [28dfce3](https://github.com/umanio-agency/skillctl/commit/28dfce3)\n- Release: https://github.com/umanio-agency/skillctl/releases/tag/v0.1.3\n- Prior advisory (path-safety + symlinks): [GHSA-wx3m-whqv-xv47](https://github.com/umanio-agency/skillctl/security/advisories/GHSA-wx3m-whqv-xv47)",
"severity" : [ ],
"affected" : [ {
"package" : {
"ecosystem" : "crates.io",
"name" : "skillctl"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "0.1.3"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/umanio-agency/skillctl/security/advisories/GHSA-74p7-6h78-gw8p"
}, {
"type" : "WEB",
"url" : "https://github.com/umanio-agency/skillctl/security/advisories/GHSA-wx3m-whqv-xv47"
}, {
"type" : "WEB",
"url" : "https://github.com/umanio-agency/skillctl/commit/28dfce3"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/umanio-agency/skillctl"
}, {
"type" : "WEB",
"url" : "https://github.com/umanio-agency/skillctl/releases/tag/v0.1.3"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-22", "CWE-400", "CWE-59", "CWE-88", "CWE-93" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-06-22T22:45:16Z",
"nvd_published_at" : null
}
}