T09 · Insecure Skill Coding Practices
- Location
scripts/script.sh:41- Finding
Unrestricted Scaffold Destination Permits Arbitrary File Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/script.sh, lines 41 and 54–56; repeated at lines 73 and 81–83, 97 and 108–110, 125 and 135–137, 149 and 158–160, and 172 and 181–183
Vulnerability Type: Unvalidated filesystem path and unsafe file overwrite
Risk Level: MediumVulnerable Code
Each scaffold implementation derives its destination directly from the user-controlled project name:
python name = sys.argv[1] base = nameIt then creates directories and opens every generated file in truncating write mode:
python for path, content in files.items(): full = os.path.join(base, path) os.makedirs(os.path.dirname(full), exist_ok=True) with open(full, 'w') as f: f.write(content) created.append(full) print(f" \033[0;32m✅\033[0m {full}")Equivalent write loops are present in all six scaffold functions.
Technical Analysis
The
initcommand accepts the project name from a command-line argument and uses it directly as the base filesystem path. It does not reject absolute paths, normalize and constrain the destination to an approved workspace, detect path traversal, check for symbolic links, or require confirmation before modifying an existing destination.Python's
open(full, 'w')truncates an existing file before writing. Consequently, selecting an existing directory can silently replace files whose relative names match the selected template, such asREADME.md,.gitignore,package.json,go.mod, ormain.go. Filesystem operations may also follow symbolic links.This behavior is not necessary for the minimum functionality of generating a new scaffold. A scaffold generator can instead require a new destination under a designated workspace and refuse existing files by default.
The static pre-scan warning concerning executable retrieval is a false positive. Lines 175–176 contain strings that generate ordinary Go source files. The audited imp ...[truncated 1459 chars]
- Remediation
View remediation
Remediation Suggestions
- Reject absolute project paths and project names containing
.., path separators, NUL characters, or platform-specific path escape forms. - Resolve the requested destination with
pathlib.Path.resolve()and verify that it remains beneath an explicitly approved workspace directory. - Require the destination directory to be absent or empty by default. Abort if it already exists unless the user supplies an explicit
--forceoption. - Use exclusive file creation, such as Python mode
xoros.open()withO_CREAT | O_EXCL, to prevent accidental truncation. - Detect and reject symbolic links in the destination path and generated file targets. Where supported, use no-follow filesystem options.
- Before any forced overwrite, display the resolved destination and exact files that will be replaced, then require explicit confirmation.
- Apply the same centralized destination-validation routine to all six scaffold functions to prevent inconsistent protections.
- Add tests covering absolute paths,
../traversal, existing destinations, existing files, and symbolic-link targets.
- Reject absolute project paths and project names containing
