T09 · Insecure Skill Coding Practices
- Location
index.js:31- Finding
OS Command Injection Through Node.js CLI Arguments
- Content
View full analysis
{ const scriptPath = path.join(__dirname, 'scripts', scriptName); if (!fs.existsSync(scriptPath)) { reject(new Error(`Script not found: ${scriptPath}`)); return; } const cmd = `python3 "${scriptPath}" ${args.join(' ')}`; console.log(`🚀 Running: ${cmd}`); exec(cmd, (error, stdout, stderr) => { ``` ### Technical Analysis The wrapper constructs a command string by concatenating command-line arguments with `args.join(' ')` and passes the result to `child_process.exec()`. Because `exec()` invokes a system shell, shell metacharacters in an argument are interpreted as command syntax rather than as literal Python arguments. The script path is quoted, but the attacker-controlled arguments are not escaped or quoted. Validation by the Python scripts occurs only after the shell has already interpreted the command. ### Attack Path 1. An attacker invokes one of the supported wrapper commands. 2. The attacker places a shell operator and an additional command inside an option value. 3. `process.argv.slice(2)` preserves the malicious input. 4. `args.join(' ')` inserts it directly into `cmd`. 5. `exec()` passes the constructed string to the system shell. 6. The injected command executes with the privileges of the Node.js process. For example, a malicious argument containing a command separator could cause the shell to run an additional local command before or after the intended Python script. ### Impact Assessment Successful exploitation provides arbitrary command execution under the account running the Skill. The attacker can read or modify files accessible to that account, execute installed programs, access environment variables, and potentially use ...[truncated 140 chars]- Remediation
View remediation
{ if (error) { reject(new Error(`Script failed: ${error.message}`)); return; } resolve(stdout); } ); ``` ]]>
