T09 · Insecure Skill Coding Practices
- Location
scripts/webhook-handler.js:277- Finding
Remote Command Injection Through Attacker-Controlled Email Subjects
- Content
View full analysis
" --thread-id "" -m ${JSON.stringify(text)}`; console.log('🔧 Exec command:', command); console.log('🔧 PATH:', env.PATH.substring(0, 200)); const { stdout, stderr } = await execAsync(command, { env, timeout: 30000 }); ``` ```javascript // scripts/send-telegram-notification.js const message = `Invoice processed: ${result.subject} - ${result.status}`; execSync(`openclaw send --to "${TELEGRAM_CHAT_ID}:${TELEGRAM_TOPIC_ID}" "${message.replace(/"/g, '\\"')}"`, { stdio: 'inherit', }); ``` ### Technical Analysis The email subject is controlled by an external sender and is incorporated into a command string passed to `child_process.exec()` or `execSync()`. Both APIs invoke a shell. `JSON.stringify()` and replacement of double quotes are not shell-escaping mechanisms. Shell expansions such as command substitution may still be interpreted inside double-quoted arguments. Consequently, a malicio ...[truncated 1763 chars]- Remediation
View remediation
{ const child = spawn( 'openclaw', [ 'message', 'send', '--channel', 'telegram', '--target', process.env.TELEGRAM_CHAT_ID, '--thread-id', process.env.TELEGRAM_THREAD_ID, '-m', text, ], { shell: false, env: process.env, stdio: ['ignore', 'pipe', 'pipe'], } ); child.once('error', reject); child.once('close', code => { if (code === 0) resolve(); else reject(new Error(`openclaw exited with code ${code}`)); }); }); } ``` 3. Apply the same correction to `scripts/send-telegram-notification.js`. 4. Treat all email-derived values, including subjects, sender addresses, attachment names, supplier names, and error text, as untrusted. 5. Run the webhook service under a dedicated, unprivileged operating-system account with minimal filesystem access. 6. Rotate Microsoft 365 and Telegram credentials after remediation if the vulnerable service has been publicly reachable. 7. Add regression tests using subjects containing quotes, semicolons, backticks, dollar signs, and command-substitution syntax, verifying that none are interpreted by a shell. ]]>
