The Model Context Protocol ecosystem has grown to nearly 10,000 servers. According to the Trend Micro AI Security Report (2025), out of 9,695 analyzed MCP servers, 5,832 exhibited unsafe patterns. That's not a rounding error — that's a systemic failure.
Over the past month, my team has been conducting a systematic security audit of open-source MCP servers. We've scanned 50+ repositories across 6 rounds, cataloging 53 distinct vulnerabilities. Some were expected — misconfigured CORS headers, missing auth. Others were far more serious.
In this article, I want to share what we found, what patterns separate secure servers from dangerous ones, and why I believe the ecosystem needs to shift from static analysis to runtime verification.
The Two P0 Cases That Changed My Perspective
Case 1: AWS Credentials at the Mercy of bash -c
The first critical vulnerability we found was in an AWS CLI wrapper MCP server. The server accepted natural language commands from the LLM, then executed them via subprocess.run(["bash", "-c", user_command]) — with zero validation, zero sanitization, zero sandboxing.
The LLM-generated command ran in a bash shell with full access to the host machine's AWS credentials — AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN — all inherited through environment variables.
Severity: CVSS 9.8. Remote code execution with cloud credential theft. No user interaction required beyond a normal conversation with the AI.
Case 2: The Azure Attack Chain — CORS + DNS Rebinding + Cloud Shell
The second critical finding was even more alarming. An Azure Cloud Shell MCP server had three vulnerabilities that chained together into a remote attack path:
-
CORS with wildcard (
*): The HTTP MCP endpoint accepted requests from any origin -
No DNS rebinding protection: The server didn't validate the
Hostheader - Unrestricted command execution: Azure Cloud Shell commands ran with full subscription access
The attack chain: A victim visits a malicious website → cross-origin request to the MCP server → DNS rebinding bypasses protections → attacker sends commands to Azure Cloud Shell → full Azure subscription access.
No user interaction required beyond visiting a webpage. CVSS 9.8 territory.
The Spectrum: From Dangerous to Well-Built
Tier P0: Complete Exposure (2 servers)
- Direct subprocess execution with no validation
- Cloud credentials accessible via environment variables
- No sandboxing, no allowlisting
Tier P1: Local Command Execution (2 servers)
- Shell command execution with minimal controls
- No command allowlisting or argument validation
Tier P2: Incomplete Defenses (8+ servers)
- Blocklist-based filtering
- Missing edge cases: encoding bypasses, path traversal
Tier Safe: Professional Implementation
The best example: cloud-mcp-server (★185, by DoIT International).
- OS-level sandboxing via Landlock / bubblewrap / macOS Seatbelt
- List-based subprocess execution — never
shell=True - Explicit path allowlists
- Credential isolation
- Fail-closed defaults
Why Static Scanning Isn't Enough
- Prompt injection → command injection: The vulnerability is in the data flow, not the code pattern
- Environment variable inheritance: Static analysis doesn't track credential flow
- CORS + DNS rebinding chains: Vulnerabilities only emerge at runtime
- LLM unpredictability: Static analysis assumes deterministic inputs
What We Built: Runtime Verification
After finding these vulnerabilities, we built Correctover — an MCP runtime verification layer.
Key capabilities:
- Parameter validation: Catches malformed tool call parameters before execution
-
Path traversal detection: Blocks
../../etc/passwdstyle attacks - Credential leak prevention: Detects when tools try to exfiltrate secrets
- Fail-closed by default: When in doubt, deny the request
We've validated it against our 53-vulnerability dataset.
What MCP Server Authors Should Do Today
Immediate (Critical)
- Audit shell execution paths: never use
shell=True - Isolate cloud credentials from subprocess environments
- Fix CORS: never use
Access-Control-Allow-Origin: *in production
Short-term (Important)
- Implement command allowlisting (fail-closed principle)
- Add DNS rebinding protection
- Use OS-level sandboxing
Long-term (Strategic)
- Add runtime verification for defense-in-depth
- Participate in security standards
The Numbers Don't Lie
| Category | Count |
|---|---|
| Repositories scanned | 50+ |
| Total vulnerabilities cataloged | 53 |
| P0 (cloud credential RCE) | 2 |
| P1 (local command execution) | 2 |
| P2 (incomplete defenses) | 8+ |
| Servers with good security | 38+ |
The ecosystem needs to mature its security posture. Static analysis is a start. Runtime verification is where we need to go.
This research was conducted as part of the Correctover MCP security audit initiative. Vulnerabilities have been reported through responsible disclosure.
- NPM: correctover
- GitHub: Correctover
Top comments (0)