T09 · Insecure Skill Coding Practices
Error
- Location
- cleanup.sh:75
- Finding
- Arbitrary JavaScript Execution Through an Unescaped Workspace Path<![CDATA[ ## Vulnerability Details **File Location**: `cleanup.sh:75-77` **Vulnerability Type**: JavaScript source injection **Risk Level**: High ### Vulnerable Code ```bash if [[ "$JSON_OUT" -eq 1 ]]; then node -e "console.log(JSON.stringify({mode:'analyze',workspace:'$WORKSPACE',memory:{files:$file_count,lines:$total_lines,archived:$archive_count},agentsLines:$agents_lines,specsCount:$specs_count},null,2))" return fi ``` ### Technical Analysis The script interpolates the attacker-influenced `WORKSPACE` environment variable directly into JavaScript source passed to `node -e`. Although the shell quotes the overall argument, it does not encode the value for use inside a JavaScript single-quoted string. A workspace path containing a single quote and additional JavaScript syntax can terminate the intended string and inject statements into the generated program. Node.js then evaluates the resulting source rather than treating the workspace path exclusively as data. This is a source-code injection issue, not ordinary shell argument injection. Shell quoting around the `node -e` argument does not prevent the expanded value from changing the JavaScript program. ### Attack Path 1. An attacker supplies or influences the `WORKSPACE` environment variable, such as through an execution wrapper, automation configuration, or attacker-controlled workspace path. 2. The corresponding `memory` directory and expected files are prepared so that the analysis reaches its JSON output branch. 3. The victim or agent invokes: ```bash ./cleanup.sh analyze --json ``` 4. The malicious workspace value is inserted between JavaScript single quotes without escaping. 5. The injected JavaScript is evaluated by Node.js. 6. The payload can invoke APIs such as `child_process` to execute operating-system commands. ### Impact Assessment Successful exploitation provides arbitrary code execution with the privileges of the user running the skill. The payload could read or modify ...[truncated 295 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions Never interpolate workspace paths into executable JavaScript source. Pass the workspace as a data argument or environment variable and read it from Node.js: ```bash WORKSPACE_VALUE="$WORKSPACE" \ FILE_COUNT="$file_count" \ TOTAL_LINES="$total_lines" \ ARCHIVE_COUNT="$archive_count" \ AGENTS_LINES="$agents_lines" \ SPECS_COUNT="$specs_count" \ node -e ' const result = { mode: "analyze", workspace: process.env.WORKSPACE_VALUE, memory: { files: Number(process.env.FILE_COUNT), lines: Number(process.env.TOTAL_LINES), archived: Number(process.env.ARCHIVE_COUNT) }, agentsLines: Number(process.env.AGENTS_LINES), specsCount: Number(process.env.SPECS_COUNT) }; console.log(JSON.stringify(result, null, 2)); ' ``` Alternatively, use `jq` with `--arg` and `--argjson`, which safely distinguishes strings from numeric values. Add regression tests covering paths containing quotes, backslashes, newlines, Unicode characters, and JavaScript metacharacters. ]]>
