T09 · Insecure Skill Coding Practices
- Location
scripts/init_skill.py:206- Finding
Output Path Traversal in Skill Initializer
- Content
View full analysis
Vulnerability Details
File Location:
scripts/init_skill.py, lines 206–257
Vulnerability Type: Improper path validation and path traversal
Risk Level: MediumVulnerable Code
python # Determine skill directory path skill_dir = Path(path).resolve() / skill_name # Check if directory already exists if skill_dir.exists(): print(f"❌ Error: Skill directory already exists: {skill_dir}") return None # Create skill directory try: skill_dir.mkdir(parents=True, exist_ok=False) print(f"✅ Created skill directory: {skill_dir}") except Exception as e: print(f"❌ Error creating directory: {e}") return None # Create SKILL.md from template skill_title = title_case_skill_name(skill_name) skill_content = SKILL_TEMPLATE.format( skill_name=skill_name, skill_title=skill_title ) skill_md_path = skill_dir / 'SKILL.md' try: skill_md_path.write_text(skill_content) print("✅ Created SKILL.md") except Exception as e: print(f"❌ Error creating SKILL.md: {e}") return None # Create resource directories with example files try: 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) references_dir = skill_dir / 'references' references_dir.mkdir(exist_ok=True) example_reference = references_dir / 'api_reference.md' example_reference.write_text(EXAMPLE_REFERENCE.format(skill_title=skill_title)) assets_dir = skill_dir / 'assets' assets_dir.mkdir(exist_ok=True) example_asset = assets_dir / 'example_asset.txt' example_asset.write_text(EXAMPLE_ASSET) except Exception as e: print(f"❌ Error creating resource directories: {e}") return NoneTechnical Analysis
The
skill_namecommand-line argument is appended directly to the resolved base directory without enforcing the naming restrictions displayed by the ...[truncated 1717 chars]- Remediation
View remediation
Remediation Suggestions
- Validate
skill_namebefore using it as a path component:- Require a strict expression such as
^[a-z0-9-]{1,64}$. - Reject leading or trailing hyphens and consecutive hyphens.
- Reject absolute paths, path separators,
.components, and..components.
- Require a strict expression such as
- Resolve both the base and final paths, then enforce containment:
python base_dir = Path(path).resolve() if not re.fullmatch(r"[a-z0-9]+(?:-[a-z0-9]+)*", skill_name): raise ValueError("Invalid skill name") skill_dir = (base_dir / skill_name).resolve() if not skill_dir.is_relative_to(base_dir): raise ValueError("Skill path escapes the output directory")- Apply validation inside
init_skill()rather than only in command-line handling so imported callers receive the same protection. - Preserve
exist_ok=Falseand fail closed on ambiguous path or permission errors. - Add tests covering absolute names,
../traversal, nested separators, repeated hyphens, and valid skill names.
- Validate
