T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/init_skill.py:206
- Finding
- Output Path Traversal in Skill Initializer## Vulnerability Details **File Location**: `scripts/init_skill.py`, lines 206–257 **Vulnerability Type**: Improper path validation and path traversal **Risk Level**: Medium ### Vulnerable 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 None ``` ### Technical Analysis The `skill_name` command-line argument is appended directly to the resolved base directory without enforcing the naming restrictions displayed by the ...[truncated 1717 chars]
- Remediation
- ## Remediation Suggestions 1. Validate `skill_name` before 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. 2. 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") ``` 3. Apply validation inside `init_skill()` rather than only in command-line handling so imported callers receive the same protection. 4. Preserve `exist_ok=False` and fail closed on ambiguous path or permission errors. 5. Add tests covering absolute names, `../` traversal, nested separators, repeated hyphens, and valid skill names.
