T09 · Insecure Skill Coding Practices
- Location
index.js:57- Finding
OS Command Injection in the Node.js Transcription Wrapper
- Content
View full analysis
{ const scriptPath = path.join(__dirname, 'scripts', 'transcribe.py'); // 构建命令 let cmd = `python3 ${scriptPath} "${audioPath}"`; cmd += ` --mode ${modelMode}`; cmd += ` --format ${format}`; cmd += ` --segment ${segmentSeconds}`; if (verbose) cmd += ' --verbose'; if (noWait) cmd += ' --no-wait'; console.log(`[FunASR] 模式: ${modelMode}, 分段: ${segmentSeconds}s, 内存: ${modelMode === 'small' ? '~500MB' : '~2GB'}`); exec(cmd, { maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => { ``` ### Technical Analysis The `transcribe()` method constructs a command string by directly interpolating `audioPath`, `modelMode`, `format`, and `segmentSeconds`, then executes that string through `child_process.exec()`. The `exec()` API invokes a system shell, so shell metacharacters in any interpolated value are interpreted as command syntax. The preceding `fs.access(audioPath)` check does not neutralize this vulnerability. On supported filesystems, a real filename can contain quotes, command-substitution characters, semicolons, or other shell-significant characters. Additionally, direct callers of the exported `transcribe()` method are not constrained by the OpenClaw tool schema and can provide arbitrary option values. Quoting only `audioPath` with double quotes is insufficient because embedded double quotes and command substitutions can escape or remain active within the resulting shell command. ### Attack Path 1. An attacker gains control over a path or option passed to the exported `transcribe()` method. 2. The attacker supplies an existing audio filename containing shell syntax, or directly ...[truncated 966 chars]- Remediation
View remediation
