The remote code execution hole in MCP is a design decision
Anthropic shipped a serious rewrite of the Model Context Protocol spec on July 28. The transport core is now stateless, session IDs are gone, and OAuth gets real hardening: issuer validation, credential binding, a new client-registration scheme replacing the old one. A few older features are on a twelve-month deprecation clock. It reads like a protocol growing up. It does not touch the bug that made headlines three months earlier. That bug was never a defect in the sense a spec revision can patch. It is a design decision, and the response to the disclosure treated it as one.
The decision: MCP’s stdio transport takes a command string out of a server configuration and executes it as a subprocess, on every officially supported SDK, with no sanitization and no allowlist. In April, OX Security published research documenting the blast radius — 150 million-plus SDK downloads carrying the pattern, more than 7,000 publicly reachable servers, up to 200,000 vulnerable instances, ten CVEs across affected products. The researchers didn’t stop at counting. They submitted a test payload to eleven public MCP registries; nine accepted it without review. Six live production platforms with paying customers ran it.
No protocol change followed, and the defence of the design is coherent. Stdio’s entire job is launching an arbitrary local process on the developer’s behalf, and a command string you can sanitize without breaking arbitrary-process launch is a contradiction in terms. Trust boundary: whoever writes the config. If you can edit it, you were already allowed to run code on that machine. The visible remediation was a guidance update recommending these adapters be used with caution — a documentation change, not a protocol one. SecurityWeek headlined it a “by design” flaw, which is the entire argument compressed into two words.
That argument holds up on its own terms — it runs the same logic that makes exec() dangerous in any language, and nobody opens a CVE against libc for it. What changed is who gets to put a string into that field. A stdio config used to be something a developer wrote once, by hand, on their own machine. MCP added a marketplace on top of that assumption — registries, one-line install commands, agents that read a tool’s description and configure it themselves. The design assumes a human typed the command and meant it. OX’s most effective attack chains never needed that human: a poisoned registry entry, an IDE’s zero-click prompt injection, an agent following instructions buried in content it was only asked to summarize. The command field stayed exactly as trusted as it always was. Everything feeding it stopped being trustworthy.
This failure has a name: the confused deputy. It comes from a 1988 paper describing a compiler with legitimate rights to a billing file that could be tricked into overwriting it on someone else’s behalf. The compiler’s privileges never changed; what changed was who could steer them. MCP’s stdio transport has the identical structure at protocol scale — real, intentional privilege, exercised on behalf of a caller the transport has no way to vet.
This is also why moving MCP to neutral governance doesn’t touch the argument at all. Anthropic donated the protocol to the Agentic AI Foundation in December 2025. The project’s own governance charter now seats maintainers as individuals rather than company delegates. That structure answers who sets the roadmap and who can’t unilaterally rewrite the wire format on their own authority. It has nothing to say about whether an unsanitized subprocess call is correct behavior, because that was never a governance dispute. Every account of it agrees on the facts and disagrees only on whether the facts describe a bug. A steering group with veto rights over specification changes can’t referee a question the original designers already answered when they built the transport.
My bet is this gets resolved the way most of these do — outside the spec, not inside it. Today’s MCP registries verify publisher identity through GitHub OIDC or a DNS record. That’s enough to catch typosquatting and nothing more. There’s still no cryptographic signing tying a server name to a specific attested binary. That’s the actual opening. It’s one a registry operator can close without Anthropic changing a line of the transport: signed packages, command allowlisting, a curated tier that a fast-moving impersonator can’t buy its way into. Whoever builds that becomes the real security boundary the core spec declined to be, while stdio keeps doing precisely what it was designed to do, indefinitely.