T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/template.py:293
- Finding
- Path Traversal Enables Arbitrary File Creation and Overwrite## Vulnerability Details **File Location**: `scripts/template.py`, lines 293–310 **Vulnerability Type**: Path traversal and unrestricted file write **Risk Level**: High ### Vulnerable Code ```python # Convert name to appropriate format safe_name = name.replace(' ', '_').replace('-', '_') class_name = ''.join(word.capitalize() for word in name.replace('-', ' ').split()) print(f"Creating {template['description']} in {output_dir}/") for filename, content in template['files'].items(): # Replace placeholders filename = filename.format(name=safe_name, Name=class_name) content = content.format(name=safe_name, Name=class_name) file_path = output_path / filename # Create parent directories file_path.parent.mkdir(parents=True, exist_ok=True) # Write file with open(file_path, 'w') as f: f.write(content) ``` ### Technical Analysis The `name` argument is attacker-controlled. Its only sanitization replaces spaces and hyphens with underscores; it does not reject path separators, absolute paths, `.` components, or `..` traversal components. Templates such as `class` and `react` use `{name}` in generated filenames. After placeholder formatting, the resulting filename is joined to the requested output directory without canonicalization or a containment check. A value containing `../` can therefore escape the intended output directory. An absolute path can also cause `pathlib.Path` to disregard the preceding output directory. The code creates missing parent directories and opens the destination using mode `w`. Consequently, it can create files outside the output directory or silently truncate and replace an existing file. No explicit overwrite confirmation, exclusive file creation, resolved-path validation, or symbolic-link protection is present. ### Attack Path 1. An attacker or untrusted caller invokes the generator with a template whose filename contains `{name}`, such as `c ...[truncated 1483 chars]
- Remediation
- ## Remediation Suggestions 1. Enforce a strict allowlist for generated names. For example, accept only identifiers matching an appropriate expression such as `^[A-Za-z_][A-Za-z0-9_]*$`. 2. Explicitly reject absolute paths, `/`, `\`, null bytes, `.` components, and `..` components in values used to construct filenames. 3. Resolve both the output root and candidate destination, then verify that the destination remains beneath the output root before creating directories or opening the file. 4. Reject symbolic-link destinations and consider opening files through a directory file descriptor with platform-appropriate no-follow protections where hostile users can modify the output tree. 5. Use exclusive creation mode (`x`) by default so existing files are not silently overwritten. Require an explicit, clearly documented option to permit replacement. 6. Keep display names separate from filesystem-safe names rather than applying partial character substitutions to untrusted input. 7. Add regression tests covering `../name`, absolute paths, nested traversal, alternate path separators, symbolic links, and attempts to overwrite existing files. 8. Align `SKILL.md` with the actual bundled functionality so users understand that `scripts/template.py` generates and writes project files, including the affected security boundary.
