Summary
The interact_with_process MCP tool does not call commandManager.validateCommand() before sending input to a running process. This means the blockedCommands configuration has zero effect when commands are injected through an interactive process.
How This Differs from Known Limitations
Your SECURITY.md correctly notes that command blocking can be bypassed via substitution and absolute paths (CVE-2025-11490, CVE-2025-11491). Those are bypass techniques against a validation function that does run.
This finding is different: interactWithProcess() has no validation call at all. The startProcess() function correctly calls commandManager.validateCommand() at line ~103 of improved-process-tools.ts, but interactWithProcess() — which sends arbitrary input to running processes — completely skips this step.
Attack Chain
1. start_process("python3 -i") → ALLOWED
2. interact_with_process(pid,
"import os; os.system('dd if=/dev/zero of=/tmp/pwned bs=4 count=1')")
→ NO validation check
→ dd executes successfully (EXIT: 0)
All 27+ blocked commands (sudo, dd, mkfs, iptables, etc.) are reachable through this path.
Reproduction
Reproduced in Docker with the recommended Docker setup:
docker run --rm -it node:20-bookworm-slim bash
apt-get update && apt-get install -y python3
mkdir /app && cd /app
npm init -y && npm install @wonderwhy-er/desktop-commander@0.2.43
Then run the assessment script (attached below or available on request).
Verification Output
start_process → dd if=/dev/zero of=/tmp/test bs=4 count=1
Response: Error: Command not allowed ← Correctly blocked
interact_with_process → Python os.system("dd if=/dev/zero...")
Response: 1+0 records in, 1+0 records out, EXIT: 0
File written: /tmp/BYPASS-* ← Bypassed
Root Cause
File: src/tools/improved-process-tools.ts
startProcess(): ✅ has await commandManager.validateCommand(parsed.data.command) at line ~103
interactWithProcess(): ❌ no call to commandManager.validateCommand()
The fully functional validation method exists in src/command-manager.ts — it handles path normalization, command substitution detection ($(), backticks), and multi-command parsing. It is simply not wired into interactWithProcess().
Suggested Fix
One call in interactWithProcess() before sending input:
if (parsed.data.input) {
const isValid = await commandManager.validateCommand(parsed.data.input);
if (!isValid) {
return { content: [{ type: "text", text: "Input rejected: contains blocked command." }], isError: true };
}
}
I recognize the project's stated position that these restrictions are guardrails rather than a security boundary. The inconsistency between start_process (enforced) and interact_with_process (unchecked) is worth noting because users who configure blockedCommands based on start_process's behavior may not realize the gap.
Happy to discuss further. Attribution: nobugpal (if desired).
Summary
The
interact_with_processMCP tool does not callcommandManager.validateCommand()before sending input to a running process. This means theblockedCommandsconfiguration has zero effect when commands are injected through an interactive process.How This Differs from Known Limitations
Your SECURITY.md correctly notes that command blocking can be bypassed via substitution and absolute paths (CVE-2025-11490, CVE-2025-11491). Those are bypass techniques against a validation function that does run.
This finding is different:
interactWithProcess()has no validation call at all. ThestartProcess()function correctly callscommandManager.validateCommand()at line ~103 ofimproved-process-tools.ts, butinteractWithProcess()— which sends arbitrary input to running processes — completely skips this step.Attack Chain
All 27+ blocked commands (sudo, dd, mkfs, iptables, etc.) are reachable through this path.
Reproduction
Reproduced in Docker with the recommended Docker setup:
Then run the assessment script (attached below or available on request).
Verification Output
Root Cause
File:
src/tools/improved-process-tools.tsstartProcess(): ✅ hasawait commandManager.validateCommand(parsed.data.command)at line ~103interactWithProcess(): ❌ no call tocommandManager.validateCommand()The fully functional validation method exists in
src/command-manager.ts— it handles path normalization, command substitution detection ($(), backticks), and multi-command parsing. It is simply not wired intointeractWithProcess().Suggested Fix
One call in
interactWithProcess()before sending input:I recognize the project's stated position that these restrictions are guardrails rather than a security boundary. The inconsistency between
start_process(enforced) andinteract_with_process(unchecked) is worth noting because users who configureblockedCommandsbased onstart_process's behavior may not realize the gap.Happy to discuss further. Attribution: nobugpal (if desired).