T09 · Insecure Skill Coding Practices
- Location
scripts/init_project.sh:7- Finding
Project Name Injection Enables Arbitrary Command Execution and Filesystem Writes
- Content
View full analysis
/dev/null || true ``` ### Technical Analysis The first command-line argument is accepted as `PROJECT_NAME` without validation or escaping. The same untrusted value is used in two security-sensitive contexts: 1. It becomes part of `PROJECT_DIR`, allowing path separators and `..` components to influence where the template is copied. 2. It is interpolated directly into a GNU `sed` program inside a double-quoted shell string. Shell quoting does not make the value safe for the `sed` language. An argument containing `/`, a newline, or other `sed` metacharacters can terminate the intended substitution and introduce additional `sed` commands. GNU `sed` supports the `e` command, which executes an operating-system command. For example, an attacker capable of controlling the script argument and preparing the required parent directory can use a value structurally equivalent to: ```bash $'safe/g\ne touch PWNED\n#' ``` This can transform the generated `sed` program into commands equivalent to: ```sed s/{{projectName}}/safe/g e touch PWNED #/g ``` The injected `e touch PWNED` command is then executed with the privileges of the user running the initialization script. The path construction is independently unsafe. Values containing `../` or path separators can direct `cp -r` outside the expected project-output location. Quoting prevents shell word splitting but does not prevent path traversal. The trailing `|| tr ...[truncated 1571 chars]- Remediation
View remediation
&2 exit 1 fi if [[ "$PROJECT_NAME" == "." || "$PROJECT_NAME" == ".." ]]; then echo "Invalid project name" >&2 exit 1 fi ``` 2. Reject all path separators, traversal components, control characters, and newlines. 3. Resolve the destination to a canonical path and verify that it remains below an explicitly approved output directory. 4. Do not generate an executable `sed` program using untrusted text. Use a small Node.js or Python script that reads files as data and performs literal string replacement. 5. If `sed` must be retained, escape replacement metacharacters such as `\`, `/`, and `&`; strict input validation should still be applied. 6. Fail closed when replacement fails. Remove `2>/dev/null || true` and report partial initialization errors. 7. Refuse to overwrite existing destinations unless the user explicitly approves the operation. 8. Run the script with ordinary user privileges and in a restricted workspace, particularly in CI environments. ]]>
