DEV Community

Bobby Blaine
Bobby Blaine

Posted on • Originally published at robbyb910.substack.com

Your MCP Server Is Probably Vulnerable

In January and February 2026, security researchers filed 30 CVEs against MCP servers in just 60 days. Among 2,614 surveyed implementations, 82% were vulnerable to path traversal. The worst offender, CVE-2025-6514, scored a CVSS 9.6 for remote code execution in a package with 437,000 downloads. MCP security vulnerabilities are no longer theoretical.

The Scale of the Problem

The Vulnerable MCP Project now tracks 50 vulnerabilities across the MCP ecosystem, 13 of them critical. Thirty-two security researchers from organizations including SentinelOne, Snyk, Trail of Bits, and CyberArk have contributed findings. The numbers are bad for AI agent security.

The breakdown by attack type tells you where the real rot is: 43% are shell or exec injection, 20% are tooling infrastructure flaws, 13% authentication bypass, and 10% path traversal. That means over half the CVEs come down to MCP servers passing unsanitized input to shell commands or file system operations. The remaining 14% covers SSRF, cross-tenant data exposure, and supply chain attacks.

It gets worse when you look at the baseline. Of those 2,614 servers surveyed, 67% had code injection risk, 34% were susceptible to command injection, and 36.7% were exposed to SSRF. Between 38% and 41% lacked any authentication mechanism at all. These are not obscure hobby projects. The Framelink Figma MCP Server alone has over 600,000 downloads and 10,000 GitHub stars.

The protocol grew faster than its security practices. With 97 million installs across the ecosystem, MCP became the de facto standard for connecting AI agents to tools. Anthropic published the spec in late 2024, and by early 2026 every major IDE, AI assistant, and automation platform had adopted it. Security was an afterthought. The result is an ecosystem where most servers were built to demo well, not to withstand adversarial input.

MCP Server Hardening: Specific Threats and Fixes

Three attack classes deserve your attention right now.

Tool poisoning is the hardest to detect. Invariant Labs demonstrated that malicious instructions hidden in MCP tool descriptions can direct an AI model to exfiltrate SSH keys and config files. The user sees a friendly tool name in the approval UI. The model sees the full description, including concealed directives to read ~/.ssh/id_rsa and transmit it through tool parameters. In controlled testing, these attacks succeed 84.2% of the time when agents run with auto-approval enabled. And 5.5% of public MCP servers already have poisoned descriptions in the wild.

The poisoned tool does not even need to be called. Merely being loaded into context is enough for the model to follow hidden instructions. There are three variants: direct poisoning hides instructions in descriptions, tool shadowing lets a malicious server override a trusted tool's behavior, and rug pulls appear safe initially before silently modifying tool definitions on subsequent connections.

Command injection accounts for the largest share of CVEs. CVE-2026-5058 in aws-mcp-server carries a CVSS 9.8 and allows remote code execution through crafted input to AWS CLI wrappers. CVE-2026-5741 in docker-mcp-server enables OS command injection through version 0.1.0. CVE-2026-23744 in MCPJam Inspector is worth special attention: versions up to 1.4.2 listen on 0.0.0.0 with no authentication. A crafted HTTP request can install an MCP server and execute arbitrary code on the host. The pattern across all of these is the same: user-controlled input reaches a shell exec call without sanitization. If you have built an MCP server that calls child_process.exec() or subprocess.run(shell=True) with any parameter derived from tool input, you almost certainly have this bug.

Cross-client data leaks are the third major class. CVE-2026-25536 in the MCP TypeScript SDK causes responses to leak across client boundaries when a single McpServer instance is reused. One client receives data intended for another. If you are running multi-tenant MCP infrastructure, this one matters.

For command injection, the fix is strict input validation. Set additionalProperties: false on tool input schemas so only declared parameters are accepted, and apply pattern constraints on string fields to block traversal and injection characters:

{
  "type": "object",
  "properties": {
    "filename": {
      "type": "string",
      "pattern": "^[a-zA-Z0-9_\\-\\.]+$"
    }
  },
  "additionalProperties": false
}
Enter fullscreen mode Exit fullscreen mode

Never pass tool parameters directly to shell commands. Use parameterized execution (array-form execFile in Node, list-form subprocess.run in Python) instead of string interpolation into a shell.

For tool poisoning, disable auto-approval immediately. This single change drops attack success from 84.2% to under 5%. If your workflow depends on auto-approval for speed, scope it narrowly to specific trusted servers rather than enabling it globally.

Your Five-Step MCP Audit

Here is a concrete process you can run today.

Step 1: Scan your installed servers. Run Invariant Labs' mcp-scan against every configured MCP server:

uvx mcp-scan@latest
Enter fullscreen mode Exit fullscreen mode

This detects tool poisoning, rug pulls, cross-origin escalation, and prompt injection in your current setup. Run it before and after adding any new server.

Step 2: Inspect tool descriptions manually. Use uvx mcp-scan@latest inspect to read the full text of every tool description. Look for instructions that reference file paths, environment variables, or network endpoints that have nothing to do with the tool's stated purpose. Pay special attention to tools that mention ~/.ssh, ~/.aws, .env, or any credential file paths. A legitimate calculator tool has no business referencing your SSH directory.

Step 3: Pin versions and verify hashes. Never use @latest in production MCP configs. Pin specific versions. The mcp-scan tool hashes tool descriptions on first scan and alerts you if definitions change, catching rug pull attacks.

Step 4: Containerize your servers. Run MCP servers in Docker with read-only filesystems, dropped capabilities, no-new-privileges, and isolated networks. Default-deny network egress is the single highest-impact control because it limits the blast radius of every other vulnerability class. A compromised server that cannot reach the internet cannot exfiltrate your data.

Step 5: Remove what you do not use. Every installed MCP server is attack surface. Audit your claude_desktop_config.json, .cursor/mcp.json, or equivalent config file. If you added a server to try it once three months ago, uninstall it now. The Practical DevSecOps guide calls this out as the confused deputy problem: servers sitting idle still have their tool descriptions loaded into context, still influencing agent behavior.

What to Watch For

The OWASP MCP Top 10 is the emerging framework here, but it is early days. Coverage is uneven. Most scanning tools catch tool poisoning and command injection well. They are weaker on supply chain attacks (MCP04) and shadow MCP servers (MCP09).

The mcpserver-audit tool from the Cloud Security Alliance is worth watching as a more structured alternative to mcp-scan, but it is not yet mature enough to replace it.

Authentication remains the elephant in the room. The MCP spec makes auth optional for stdio transport, which covers most local setups. For HTTP transport, OAuth 2.1 is the recommended path, but adoption is glacial. Nobody wants to be the person who tells developers their localhost tool needs an auth flow. (Everyone should be that person.)

Key Takeaway

Run uvx mcp-scan@latest against your setup today. Disable auto-approval for tool calls. Pin your server versions and containerize anything that touches production data. These four actions address the majority of the attack surface that produced 30 CVEs in 60 days. The MCP ecosystem is not going to slow down, and attackers have already noticed the gap between adoption and security posture. Close it before they walk through it.

Top comments (0)