T09 · Insecure Skill Coding Practices
- Location
cleanup.sh:82- Finding
Arbitrary JavaScript Execution Through Unsafe JSON Generation
- Content
View full analysis
/dev/null || true fi ``` ### Technical Analysis The script constructs JavaScript source code inside a double-quoted shell argument and directly embeds environment-controlled paths and filesystem-derived filenames. These values are not encoded or escaped as JavaScript string literals. At line 82, `$WORKSPACE` is inserted between JavaScript single quotes. A workspace path containing a single quote and additional JavaScript syntax can terminate the string and inject statements into the program evaluated by `node -e`. At line 119, entries in `low_list` and `medium_list` are interpolated directly into generated JavaScript. Since filenames can contain quotes and other JavaScript syntax characters, a maliciously named Markdown file can alter the evaluated program. This is source-code injection rather than ordinary malformed JSON. Injected JavaScript can access Node.js APIs such as `require("child_process")`, `fs`, and networking modules. The `2>/dev/null || true` behavior at line 119 can additionally conceal parser errors or other evidence of exploitation. ### Attack Path 1. An attacker controls the `WORKSPACE` environment variable and prepares a corresponding workspace directory whose path contains JavaScript syntax, or creates a ...[truncated 1267 chars]- Remediation
View remediation
/dev/null || true`; return a nonzero status so malformed output and attacks are visible. - Add regression tests containing filenames and workspace paths with single quotes, double quotes, backslashes, newlines, Unicode, and JavaScript metacharacters. A safer pattern for a scalar value is: ```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 output = { 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(output, null, 2)); ' ``` ]]>
