Back to Blog

Your MCP Server Is an Attack Surface

Standing up an MCP server feels like a weekend project. Except you've also shipped a privileged, internet-adjacent service into an ecosystem racking up critical CVEs faster than almost anything in recent memory. The threat model, and how not to become a statistic.

In August 2026, a security firm called Pillar Security caught a campaign they named Deadbugz, and it's the clearest picture yet of where this is all going. A single GitHub account filed twenty-three pull requests to unrelated projects in a seventy-four-minute window, each one adding a helpful-looking MCP server called "productivity-suite" that offered text formatting and summarization. The tools worked exactly as advertised. For the first two calls.

The server kept a per-client counter. On the third tool call, it quietly rewrote the descriptions it handed back to the AI agent, and the new instructions told the agent to go find SSH keys, AWS credentials, shell history, and Kubernetes config, and to hide what it was doing from the human watching. Your install-time review caught nothing, because the thing was designed not to fire until after you'd approved it.

That's not an outlier. It's a preview.

The ecosystem is on fire, quietly

Here are the numbers, because they're worse than the vibe. Between January and April 2026, researchers disclosed more than forty CVEs against MCP implementations across the Python, TypeScript, Java, and Rust SDKs. Independent scans keep finding somewhere between a third and four-fifths of public MCP servers carrying exploitable flaws, and only a small single-digit percentage using any real authentication. The single worst one, CVE-2025-6514 in the popular mcp-remote package, was a CVSS 9.6 remote-code-execution flaw that had been downloaded more than 437,000 times before anyone disclosed it. One bad dependency, four hundred thousand exposed machines.

And the pace hasn't slowed since. September 2026 alone put two more CVSS-10 findings into the record: mysql_mcp_server's SSE transport (CVE-2026-59971) shipped with no authentication and no DNS-rebinding protection, so a network attacker could reach execute_sql directly; MCP Context Forge's Python sandbox (CVE-2026-53710) let a crafted tool call walk the class hierarchy at runtime and land on subprocess.Popen, turning a "sandboxed" code-execution tool into an unsandboxed one. A week before that, CISA added LiteLLM's MCP auth bypass (CVE-2026-59822, a broken OAuth2 passthrough that handed out an empty, always-valid auth object) to its Known Exploited Vulnerabilities catalog — the first MCP flaw to ever make that list, with a federal remediation deadline attached. This isn't theoretical risk anymore; it's confirmed exploitation in the wild. And as this post goes up, Langflow's MCP project endpoints (CVE-2026-85025) turned out to let an unauthenticated visitor execute code on the server and read or write other users' live chat sessions, because the flag marking one flow "public" didn't actually keep everything else private.

MCP is less than two years old and it is already one of the most actively attacked surfaces in software. If you're running a server, you're in scope whether you meant to be or not.

Why it's nastier than a normal API

Three things make an MCP server a worse place to be careless than an ordinary web service.

One exploit hits everyone. Standardization is the whole point of MCP, and it's also the problem. Before, every integration was bespoke, so every attacker wrote a custom exploit. Now everyone speaks the same protocol, so one exploit applies across thousands of deployments. mcp-remote is the proof: a single flaw in a single proxy put every client that used it at risk at once.

The metadata is code. This is the part people miss. Your tool descriptions and schemas aren't labels for humans, they're context fed straight to the model to shape which tool it picks and how it uses it. Which makes the description field an injection channel. Deadbugz didn't exploit a memory bug, it just put instructions where the model would read them and trust them. A tool description is executable influence, and static review only ever sees the version the server felt like showing you.

A foothold is a big foothold. MCP servers tend to sit on broad ambient authority: filesystem access, API keys, a database, outbound network. Combine the three ingredients security folks now call the lethal trifecta, access to external content, access to private data, and the ability to make outbound requests, and you don't have a bug, you have an exfiltration pipeline. Most servers hand out all three without thinking about it.

The classes that actually bite

Skip the CVE-by-CVE tour; here's the shape of what goes wrong.

Metadata poisoning, the Deadbugz move: the server changes what it advertises after you've approved it. Indirect prompt injection: the model treats tool results as trusted, so a poisoned result, a booby-trapped file, a doctored API response, steers the agent. The confused deputy, which showed up at production scale this year in a real MCP server that could be talked into making API calls it shouldn't: your server has authority the user doesn't, and gets tricked into spending it on their behalf. Missing authentication, which is depressingly common, and which is exactly what let CVE-2026-59971 and CVE-2026-59822 happen. And the boring classics, command injection and path traversal, from passing model-or-user-supplied input straight into a shell, a file path, or an OS call without sanitizing it — how mcp-remote got its 9.6, and how MCP Context Forge's "sandboxed" code tool got its 10.0.

If you run one, run it like it's under attack

None of the defenses are exotic. They're just not the default, which is the whole problem.

Authenticate the server. Most public ones don't, so this alone puts you ahead of the pack. Least-privilege every tool: the narrowest scope that does the job, never a god-mode filesystem or shell tool because it was convenient. Treat three things as untrusted input, not one: the arguments coming in, the results going back, and your own tool metadata, and monitor that metadata for drift after approval, because a description that changes is a Deadbugz in progress. Require fresh consent when a server's advertised surface changes instead of silently accepting it. Allow-list dangerous operations, the specific commands, paths, and hosts you permit, rather than trying to blocklist the bad ones. Put a human in the loop for anything destructive or irreversible. Constrain outbound network access, which breaks the trifecta even when something else fails. Pin and vet your dependencies and actually watch the advisories, because mcp-remote was a dependency nobody was watching. And log every tool call, because you can't investigate what you never recorded.

The uncomfortable close: even Anthropic's own MCP Inspector shipped a critical remote-code-execution hole (CVE-2025-49596), a debugging UI with no authentication on it out of the box. If the people who wrote the protocol left the door open on their reference tooling, the odds that your weekend server is airtight are not good.

MCP's entire pitch is that wiring a tool into an agent is trivial now. That ease is exactly why the danger is invisible: it doesn't feel like standing up a privileged, internet-facing service, so nobody secures it like one. It is one. Run it accordingly.

Share this article

Want to Work Together?

Let's discuss how I can help with your project.

Get in Touch