Insights Business| SaaS| Technology The By Design Architectural Flaw and Why Patching Won’t Solve MCP Security
Business
|
SaaS
|
Technology
May 22, 2026

The By Design Architectural Flaw and Why Patching Won’t Solve MCP Security

AUTHOR

James A. Wondrasek James A. Wondrasek
Graphic representation of the topic The By Design Architectural Flaw and Why Patching Won't Solve MCP Security

When OX Security published its audit of 7,000+ publicly accessible MCP servers in April 2026, the finding that landed hardest wasn’t the CVE count. It was Anthropic’s response. Asked to patch the root cause — the mechanism that allowed arbitrary command execution on any host running an MCP server — Anthropic said the behaviour was “expected.” Not a bug. Not an oversight. Expected.

Fourteen-plus CVEs have since been patched. The security community has largely moved on. The evidence says that’s a mistake.

Here’s the structural problem: any MCP server can request host-system access at the OS level via the STDIO transport model. That capability is in the protocol design, not in a coding error in a specific implementation. Patching individual CVEs cannot remove it. And conventional security controls — DLP, EDR, WAF — produce no signal on this attack class, because their inspection models were never built for natural-language attack surfaces.

This article makes the case that patching is not enough, and explains what would actually close the risk. For the full picture of the OX audit, see our MCP security hub.


What Does “By Design” Actually Mean — and Why Does It Matter More Than It Sounds?

The phrase “by design” carries a lot more technical weight than most commentators have given it.

A CVE identifies a deviation from intended behaviour: a developer made an error, the implementation diverged from the design, and patching restores the intended state. “By design” is categorically different. The intended behaviour is the problem. Patching cannot change intent. Only a redesign can.

When OX Security reframed this as a “by design flaw” — a framing picked up by CSO Online, The Hacker News, and Security Week as “RCE by design” — they weren’t being rhetorical. They were identifying that the trust problem is embedded in the protocol specification itself, across all supported languages in Anthropic’s official MCP SDK. This architectural decision “has silently propagated into every language, downstream library, and project that relies on the protocol.”

Anthropic’s position is technically accurate: STDIO subprocess execution is a protocol feature, and input sanitisation is the developer’s responsibility. OX Security’s response: “This change didn’t fix anything.” Both positions are coherent. They optimise for different failure assumptions — Anthropic’s assumes careful developers; OX Security’s does not. For organisations, the consequence is immediate: every MCP deployment using STDIO transport is exposed to the root cause, regardless of which CVEs have been patched.


Why Does the STDIO Transport Model Create an Unresolvable Trust Problem?

STDIO — Standard Input/Output — is an interprocess communication mechanism. When MCP uses STDIO as its transport, the MCP server runs as a subprocess of the host process, inheriting access to the host system’s OS resources. The SDK passes configuration data — file paths, commands, arguments, environment variables — directly into the parameters used to spawn the child process, without sanitisation. As Paddo.dev put it: “There is no allowlist, no sanitization, no capability scoping. The reference SDK hands the string to the OS and trusts the caller to be careful.”

Any MCP server — legitimate or malicious — can request the same OS-level access via the same mechanism. There is no protocol-level checkpoint. Compare that with HTTP/SSE transport, MCP’s alternative, which operates over a defined network boundary with explicit request/response semantics. That boundary is what enables trust enforcement. STDIO structurally lacks it.

The downstream hardening attempts tell the same story. LiteLLM shipped a hard allowlist of approved executables. OX bypassed it with a single argument-injection string. Flowise allowlisted commands; OX bypassed it by shifting dangerous behaviour into argument space. As Paddo.dev concluded: “Each maintainer is independently rediscovering the same fix, mounting it on top of a protocol that should have done the work once.”

The enterprise registry model addresses the related marketplace poisoning problem — which we look at in detail in our article on the JFrog Universal MCP Registry.


Why Can’t DLP, EDR, or WAF Detect an MCP-Based Attack?

These tools produce no signal on MCP-based attacks because their inspection models were not designed for natural-language attack surfaces. This is not a configuration problem. It is an architectural mismatch.

DLP — Data Loss Prevention monitors for data crossing a defined boundary. An MCP-based attack exfiltrates data as a subprocess operation — one DLP sees as a legitimate process invocation. As Kiteworks documented: “DLP rules built around file exfiltration, USB transfers, or suspicious email attachments do not fire on an agent making an API call it is authorised to make.”

EDR — Endpoint Detection and Response monitors endpoint behaviour for deviations from baseline. STDIO subprocess execution is architecturally indistinguishable from legitimate tool use at the OS layer. There is no anomalous syscall signature to detect.

WAF — Web Application Firewall inspects inbound HTTP traffic. STDIO transport does not operate over HTTP. The malicious payload is embedded in natural-language tool description text, not HTTP parameters.

The mechanism that defeats all three is the same: the attack surface lives in natural-language tool descriptions, not in code. Prompt injection embeds instructions in a malicious MCP tool description that manipulate the LLM into triggering OS-level subprocess calls. These security tools predate LLM-based tool execution by decades. They are operating correctly — the attacks are architecturally outside their inspection surface.


Why Doesn’t Patching Individual CVEs Close the Root Cause?

Paddo.dev documented four CVE bypass families — four distinct attack paths that remain viable after patching because each exploits the architectural trust model, not the specific code that was patched.

Family 1 — Direct injection: Multiple tools accepted arbitrary command and argument fields through public-facing UIs and passed them into STDIO parameters without allowlists. Patching one does not protect the others — they all instantiate the same root pattern.

Family 2 — Hardening bypass: Flowise and Upsonic restricted the command field to allowed executables. OX bypassed both by shifting dangerous behaviour into argument space. A string allowlist is not a trusted execution model.

Family 3 — Zero-click IDE injection: Windsurf, Cursor, Claude Code, Gemini-CLI, and GitHub Copilot were all found vulnerable. Anthropic, Google, and Microsoft each characterised the IDE class as “a known issue, or not a valid security vulnerability.”

Family 4 — Marketplace/backend hidden path: DocsGPT removed its dangerous feature from the UI, but the privileged STDIO code path remained. Crafted network requests reached the hidden path and triggered command execution.

The SDK propagation problem makes it worse. Patches to the MCP SDK do not retroactively protect downstream implementations built on unpatched versions — over 150 million combined downloads across npm and PyPI, all inheriting the same architectural exposure.

And then there is marketplace poisoning — a zero-CVE attack vector. OX submitted a benign proof-of-concept to 11 marketplaces; 9 of 11 accepted it without security review. A malicious MCP server published to a registry exploits the STDIO trust model with no coding error required. There is no patch for it because it is not a bug.

An organisation that has patched all 14+ CVEs and considers itself protected has addressed the symptoms, not the disease. See our examination of the original CVE disclosure for the full technical account.


How Does MCP Supply Chain Risk Compare to npm/PyPI Risk — and What’s Different?

The supply chain risk pattern will be familiar. npm and PyPI have seen typosquatting, dependency confusion, compromised maintainers, and registry poisoning. The mitigation playbook took a decade to develop.

MCP is in the analogous position to npm circa 2010, but three structural differences make the risk profile worse, not equivalent.

Execution timing. npm attacks execute at install time — a discrete, auditable event. MCP attacks execute at runtime, triggered by natural-language tool descriptions. The execution boundary is invisible to conventional audit tooling.

Sandboxing. npm’s postinstall scripts run in a constrained context. STDIO subprocess execution in MCP has no protocol-level sandbox. The blast radius per compromised component is structurally larger.

Ecosystem maturity. npm and PyPI have a decade of supply chain hardening. MCP has nine malicious test packages accepted by 9 of 11 registries without review.

As Paddo.dev put it: “MCP is choosing the 1999-era posture. That is a choice, not a law of physics.”


Model-Layer Guardrails vs. Data-Layer Governance — Which Actually Limits the Blast Radius?

Every team deploying MCP faces a governance choice most haven’t framed yet: rely on probabilistic model-layer controls, or enforce deterministic data-layer controls?

Model-layer guardrails are instructions, system prompts, or fine-tuning applied to the LLM. They are probabilistic. A sufficiently crafted prompt injection in a malicious MCP tool description can override them — and Obsidian Security‘s research confirms that every major platform that has shipped prompt-injection defences has subsequently had them bypassed.

Data-layer governance enforces controls at the point of data access. These are deterministic — a data-layer control blocks the action irrespective of what the model was told to do. Every request is authenticated independently, evaluated against access policies in real time, and logged. If the agent tries to exceed its authorisation, the data layer refuses.

The distinction matters most when you think about blast radius. OWASP LLM06 (Excessive Agency) is blunt on the numbers: 90% of AI agents currently hold excessive privileges, and agents move 16x more data than human users. An agent at machine speed with legitimate credentials can extract thousands of records in seconds.

Model-layer guardrails are not worthless — they reduce attack surface — but they are the wrong primary control for a structural flaw. Data-layer governance is the correct primary control. The implementation details are in the MCP security action plan, but the structural choice should be made before the next CVE arrives.


What Would Actually Fix the MCP Security Problem?

There are three architectural options, in ascending order of thoroughness.

Option 1 — Manifest-only execution. All MCP servers must declare capabilities in a signed manifest before execution; runtime behaviour is restricted to declared functions. This is OX Security’s primary recommendation. It constrains the attack surface from unconstrained to declared — a meaningful improvement — but a server can still declare broad capabilities in its manifest. Mitigation, not a root-cause fix.

Option 2 — Command allowlists. Implemented in tools like LiteLLM, these restrict which OS commands a subprocess may invoke. Already shown to be bypassable. They buy time; they are not an architectural solution.

Option 3 — STDIO deprecation / migration to HTTP/SSE. This addresses the root cause rather than adding controls downstream of an untrusted boundary. HTTP/SSE operates over a defined network boundary with explicit trust enforcement semantics. It requires architectural changes and is not a near-term drop-in fix — but it is where the protocol needs to go.

The CISA Secure by Design standard demands that security be built into protocol design from inception. STDIO does not meet that standard. A protocol that places the burden of security sanitisation onto tens of thousands of developers — most of whom are not security engineers — is guaranteeing vulnerabilities at scale.

The realistic near-term path: full STDIO deprecation is not imminent. Manifest-only execution combined with data-layer governance is the most structurally sound posture available today. JFrog’s registry approach — cryptographic signing plus policy enforcement at the registry layer — is currently the most mature enterprise registry as an architectural mitigation. For the specific implementation steps, see the full remediation playbook.

For a complete overview of the MCP supply chain threat and the full range of available controls, see our complete MCP security overview.


Frequently Asked Questions

If I’ve patched all 14 CVEs, am I safe?

No. The four bypass families each exploit the STDIO architecture, not the patched code paths. A malicious MCP server can still request OS-level access after patching because that capability is the intended design. Patches to the MCP SDK also do not retroactively protect downstream deployments built on unpatched versions.

What does “RCE by design” mean in the context of MCP?

It means arbitrary OS-level command execution is an intended feature of the STDIO transport model, not an accidental coding error. “Remote” is technically imprecise — the execution is local via subprocess — but the term captures the severity: unrestricted command execution with no protocol-level checkpoint.

Why does Anthropic call it “expected behaviour” rather than admitting a flaw?

From Anthropic’s perspective, STDIO subprocess execution is operating as designed — input sanitisation is the developer’s responsibility. Both characterisations are accurate. Anthropic’s optimises for developer flexibility; OX Security’s accounts for the downstream population who are not security engineers.

Can’t I just use prompt shields or prompt injection detection to block MCP attacks?

Prompt injection detection has architectural limitations here. A malicious MCP tool description is designed to appear as legitimate natural-language instructions — distinguishing the two when they are structurally identical at the text level is a hard unsolved problem. As OpenAI has acknowledged, prompt injection “is unlikely to ever be fully solved.” Model defences and system engineering are complements, not substitutes.

What is HTTP/SSE transport, and would switching to it fix the problem?

HTTP/SSE is MCP’s alternative transport, operating over HTTP with Server-Sent Events. It operates over a defined network boundary with explicit request/response semantics, enabling trust boundary enforcement. Migrating to HTTP/SSE would remove the unrestricted subprocess execution model — but it requires architectural changes and is not a near-term drop-in fix. It also does not eliminate all supply chain risk. Data-layer governance is still required regardless of transport.

How is MCP supply chain risk worse than npm/PyPI supply chain risk?

Three differences: MCP attacks execute at runtime via natural-language triggers rather than at install time — harder to detect, no install-time gate. STDIO provides less sandboxing than npm’s execution context, so blast radius is larger. And the MCP ecosystem lacks the mature provenance and attestation tooling npm and PyPI developed over a decade.

What is manifest-only execution and does it actually fix the STDIO trust problem?

Manifest-only execution requires an MCP server to declare all capabilities in a signed manifest before running; runtime behaviour is restricted to declared functions. OX Security recommends this as the most immediately actionable structural hardening. It constrains the “any server can request anything” problem — but a server can still declare broad capabilities. Significant mitigation, not a root-cause fix.

What is data-layer governance, and how is it different from model-layer guardrails?

Model-layer guardrails influence what the LLM is willing to do — and can be bypassed by prompt injection. Data-layer governance is enforcement at the data access point: deterministic controls that block access regardless of what the model was told to do. For MCP security, data-layer governance is the correct primary control. Model-layer guardrails are a useful secondary layer.

Should I disable MCP entirely until this is resolved?

That’s operationally disruptive for teams that depend on agentic tooling. The practical near-term posture: restrict MCP deployments to servers from verified sources, implement manifest-only execution where available, enforce data-layer governance, and avoid STDIO transport for sensitive workloads where HTTP/SSE is available. Full prescriptive guidance is in the MCP security action plan.

How does Zero-Trust Architecture apply to MCP deployments?

Zero-Trust treats every component as untrusted by default and requires explicit verification at every trust boundary. Applied to MCP: every MCP server — regardless of source — should be treated as potentially malicious until its capabilities are verified and its data access is explicitly scoped. STDIO does not provide a protocol-level verification mechanism; Zero-Trust posture must be enforced at the data-layer governance level.

AUTHOR

James A. Wondrasek James A. Wondrasek

SHARE ARTICLE

Share
Copy Link

Related Articles

Need a reliable team to help achieve your software goals?

Drop us a line! We'd love to discuss your project.

Offices Dots
Offices

BUSINESS HOURS

Monday - Friday
9 AM - 9 PM (Sydney Time)
9 AM - 5 PM (Yogyakarta Time)

Monday - Friday
9 AM - 9 PM (Sydney Time)
9 AM - 5 PM (Yogyakarta Time)

Sydney

SYDNEY

55 Pyrmont Bridge Road
Pyrmont, NSW, 2009
Australia

55 Pyrmont Bridge Road, Pyrmont, NSW, 2009, Australia

+61 2-8123-0997

Yogyakarta

YOGYAKARTA

Unit A & B
Jl. Prof. Herman Yohanes No.1125, Terban, Gondokusuman, Yogyakarta,
Daerah Istimewa Yogyakarta 55223
Indonesia

Unit A & B Jl. Prof. Herman Yohanes No.1125, Yogyakarta, Daerah Istimewa Yogyakarta 55223, Indonesia

+62 274-4539660
Bandung

BANDUNG

JL. Banda No. 30
Bandung 40115
Indonesia

JL. Banda No. 30, Bandung 40115, Indonesia

+62 858-6514-9577

Subscribe to our newsletter