T09 · Insecure Skill Coding Practices
- Location
scripts/init_skill.py:195- Finding
Output Directory Escape Through Unvalidated Skill Name
- Content
View full analysis
Vulnerability Details
File Location:
scripts/init_skill.py, lines 195 and 286-287
Vulnerability Type: Path traversal and arbitrary directory creation
Risk Level: MediumVulnerable Code
python # Line 195 skill_dir = Path(path).resolve() / skill_namepython # Lines 286-287 skill_name = sys.argv[1] path = sys.argv[3]The resulting attacker-controlled path is subsequently used to create a directory and write files:
python skill_dir.mkdir(parents=True, exist_ok=False) skill_md_path = skill_dir / 'SKILL.md' skill_md_path.write_text(skill_content) scripts_dir = skill_dir / 'scripts' scripts_dir.mkdir(exist_ok=True) example_script = scripts_dir / 'example.py' example_script.write_text(EXAMPLE_SCRIPT.format(skill_name=skill_name)) example_script.chmod(0o755)Technical Analysis
The command-line help states that skill names must contain only lowercase letters, digits, and hyphens, but
main()does not enforce this restriction before passingskill_nametoinit_skill().Although the supplied base path is resolved, the final combined path is not checked for containment within that base directory. A skill name containing traversal components, such as
../../target, can escape the intended output directory. An absolute skill name can also causepathlibpath composition to discard the base path.The existence check prevents writing into an already existing target directory, but it does not prevent the creation of a new attacker-selected path elsewhere in the filesystem. The program then creates multiple files and marks the generated example script as executable.
Attack Path
- An attacker or untrusted automation controls the
skill-nameargument passed toinit_skill.py. - The attacker supplies a traversal value such as
../../attacker-target, or an absolute path to a nonexistent writable directory. - The script combines this value with the ...[truncated 1104 chars]
- An attacker or untrusted automation controls the
- Remediation
View remediation
Remediation Suggestions
-
Enforce the documented skill-name format before constructing any path:
python import re if not re.fullmatch(r'[a-z0-9]+(?:-[a-z0-9]+)*', skill_name): raise ValueError( "Skill name must contain lowercase letters, digits, and single hyphens only" ) -
Explicitly reject absolute paths, path separators,
.components, and..components. -
Resolve both the base directory and final destination, then verify containment:
python base_dir = Path(path).resolve() skill_dir = (base_dir / skill_name).resolve() if skill_dir.parent != base_dir: raise ValueError("Skill directory must be an immediate child of the output directory") -
Apply the same validation rules in both
init_skill.pyandquick_validate.pythrough a shared validation function to prevent policy drift. -
Run the utility with the minimum filesystem privileges required, particularly in automated build or packaging environments.
-
