T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/init_skill.py:196
- Finding
- Path Traversal Allows Skill Initialization Outside the Intended Directory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/init_skill.py`, lines 196-255 **Vulnerability Type**: Unvalidated path component leading to arbitrary directory creation and file writes **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: # Create scripts/ directory with example script 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) print("✅ Created scripts/example.py") # Create references/ directory with example reference doc 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)) print("✅ Created references/api_reference.md") # Create assets/ directory with example asset placeholder assets_dir = skill_dir / 'assets' assets_dir.mkdir(exist_ok=True) example_asset = assets_dir / 'example_asset.txt' ...[truncated 2584 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Validate `skill_name` before performing any filesystem operation: ```python if not re.fullmatch(r"[a-z0-9]+(?:-[a-z0-9]+)*", skill_name): raise ValueError("Invalid skill name") ``` 2. Explicitly reject absolute paths, path separators, `.` components, and `..` components. 3. 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 not skill_dir.is_relative_to(base_dir): raise ValueError("Skill directory escapes the requested output directory") ``` 4. Apply the same validation inside `init_skill()` rather than relying only on command-line parsing, because the function may be imported and called directly. 5. Create files with explicit, conservative permissions and only make generated scripts executable when that behavior is required. 6. Add regression tests covering `../name`, absolute paths, nested paths, repeated hyphens, path separators, and valid hyphen-case names. ]]>
