All rules MCP05
MCP05 — Tool Input Injection
Summary
Tool input parameters flow into child_process exec/spawn or filesystem paths without sanitisation.
Detection
AST taint trace from tool handler parameters to child_process.exec/spawn/execSync/spawnSync and unsanitised fs.* path arguments, with bounded same-file inter-procedural traversal through local helper functions. Conservative limits apply (depth cap; ambiguous same-name helpers are skipped).
Bad example
// BAD — input concatenated into a shell command
server.tool('run', async ({ cmd }) => exec(`ls ${cmd}`)); Good example
// GOOD — execFile with array args, no shell
server.tool('run', async ({ cmd }) => {
if (!/^[a-z0-9-]+$/.test(cmd)) throw new Error('invalid');
await execFile('ls', [cmd], { shell: false, timeout: 5_000 });
}); Fix
Replace exec with execFile/spawn (shell: false). Validate every input through a strict allow-list before it reaches a syscall.