T09 · Insecure Skill Coding Practices
- Location
scripts/run_all.js:12- Finding
Command Injection Through Shell-Backed Subprocess Execution
- Content
View full analysis
a.startsWith('--mode='))?.split('=')[1] || 'specific'; const topicArg = args.find(a => a.startsWith('--topic='))?.split('=')[1]; ``` ```js function runScript(scriptName, extraArgs = []) { return new Promise((resolve, reject) => { const scriptPath = path.join(__dirname, scriptName); const allArgs = [scriptPath, `--session=${sessionId}`, ...extraArgs]; console.log(`\n>>> Execute: ${scriptName}`); console.log('----------------------------------------\n'); const child = spawn('node', allArgs, { stdio: 'inherit', shell: true, }); child.on('close', (code) => { if (code === 0) { console.log(`\n<<< ${scriptName} completed`); resolve(); } else { reject(new Error(`${scriptName} exit code: ${code}`)); } }); child.on('error', (err) => { reject(err); }); }); } ``` ```js const topicArgs = topicArg ? [`--topic=${topicArg}`] : []; await runScript('01_topic_selector.js', ['--mode=specific', ...topicArgs]); ``` ### Technical Analysis The `--topic` command-line value is accepted without validation and placed into the argument array passed to `spawn()`. Although array-based argument passing is normally safe, the subprocess is explicitly created with `shell: true`. With shell execution enabled, Node.js delegates command interpretation to the operating-system shell. Shell metacharacters embedded in the topic may therefore be interpreted as command separators, redirections, substitutions, or pipelines instead of remaining literal topic text. The vulnerability is directly reachable through the documented `run_all.js` interface and does not require modification of ...[truncated 1189 chars]- Remediation
View remediation
