T09 · Insecure Skill Coding Practices
- Location
SKILL.md:107- Finding
Unvalidated Registry Values and Unsafe Archive Extraction Permit Filesystem Path Traversal
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md:64-71andSKILL.md:107-135
Vulnerability Type: Path traversal and unsafe archive extraction
Risk Level: HighThe update procedure uses registry-controlled skill names and source paths to determine local write and archive extraction destinations without requiring validation, canonicalization, or containment checks.
Vulnerable Code
yaml skills: example-dir-skill: type: github-dir source: example-owner/example-repo@main:skills/example-dir-skill version: abc123 updated: 2026-01-01text | Field | Meaning | |---------|---------| | key | skill name | | type | `github-dir` / `github-file` / `github-readme` / `local` | | source | source location | | version | commit SHA (`github-dir`) or SHA256 (file-based types) | | updated | last update date |markdown ## github-dirgh api "repos/{owner}/{repo}/tarball/{branch}" > archive.tar.gz
text Verify the file is valid gzip before extracting. Copy target path to `skills/{name}/`. ## github-filegh api "repos/{owner}/{repo}/contents/{path}?ref={branch}" -H "Accept: application/vnd.github.raw+json" > skills/{name}/SKILL.md
text Technical Analysis
The registry's skill name, repository path, and branch are editable input, but the documented procedure does not impose an allowlist or reject absolute paths, directory separators,
..components, control characters, or shell metacharacters.For
github-fileentries, the skill name is directly incorporated intoskills/{name}/SKILL.md. A name containing traversal components could resolve outside the intendedskillsdirectory. The procedure does not require canonicalizing the destination and confirming that it remains beneath the canonical skills root before writing.For
github-direntries, the only stated archive validation is checking whether the downloaded file is valid ...[truncated 2203 chars]- Remediation
View remediation
Remediation Suggestions
- Validate every registry skill name against a strict allowlist, such as
^[A-Za-z0-9._-]+$. - Explicitly reject names containing
..,/,\, absolute paths, control characters, whitespace, or shell metacharacters. - Parse
sourceinto separately validated owner, repository, branch, and path components rather than interpolating the complete value into commands. - Construct destinations through a path-safe API, canonicalize both the skills root and destination, and reject the operation unless the destination remains strictly beneath the canonical skills root.
- Download archives to a securely created temporary directory using unique filenames rather than a predictable
archive.tar.gzin the working directory. - Before extraction, inspect every archive entry and reject:
- Absolute paths
..path components- Paths resolving outside the extraction root
- Symbolic links or hardlinks whose targets escape the extraction root
- Device files and other special entries
- Extract into a fresh isolated directory without following links. Revalidate all extracted paths before copying selected content into the final destination.
- Copy only the explicitly configured repository subdirectory rather than copying the entire extracted archive.
- Write downloaded files to a temporary file, validate them, and then perform an atomic rename into the validated destination.
- Include destination paths and archive safety-check results in the approval summary so the user can review exactly what will be overwritten.
- Validate every registry skill name against a strict allowlist, such as
