Protocol Pivoting Update
In May I had one example and an argument that it was structural, not an accident. Since then at least five separate security teams, at organizations that nothing but a protocol, have each confirmed and fixed the same SSRF mistake independently.
In May I sent a writeup describing server-side request forgery in Model Context Protocol servers, and an attack class I called Protocol Pivoting. The finding was narrow. The argument was not. I said the problem was not one careless implementation but a structural gap in how MCP servers handle values that come from an agent or from an upstream service. I had one clear example. The rest was a hypothesis.
A hypothesis like that makes a prediction you can test. If the gap is structural, it should show up in servers written by teams that nothing: different industries, different countries, different codebases, no common owner. So I went and looked.
It showed up at least five times as SSRF: Google, JPMorgan Chase, Weaviate, France's interministerial digital directorate, and the Tangerang City government in Indonesia. Each one was confirmed by that organization's own security team, not by me. A fifth organization, Rapid7, published a CVE for a different but related bug. I have also reported security issues in five MCP servers built for the US federal government. Those were filed on 2 September 2026, are still in triage, and I am not presenting them as confirmed outcomes.
None of these teams code or an owner. What they is a protocol that did not exist two years ago and is already in production use, before anyone has checked it widely for this class of bug. Watching the same mistake come back from a hyperscaler, a bank, and a national government, one report at a time, is the moment the May argument stopped being a guess.
This piece is meant to stand alone. It starts with what changed, then covers the original material for anyone who has not seen it.
The two failure modes
The first is server-side request forgery. An MCP server exposes tools, an agent calls them with arguments, and some of those arguments are URLs, paths, or endpoints. If the server builds an outbound request from that value without checking where it actually resolves, the agent decides what the server's network identity talks to. Agents read untrusted content and act on it. So in practice the agent is a channel for anyone who can get text in front of it.
The second is unsafe handling of upstream data, most visibly in logging. A server gets a response from an upstream API and writes it out whole, at a level that ends up in centralized logs, without redaction. Nothing has to be attacked for this to cause harm. Ordinary errors are enough.
Both come from the same assumption. The developer treats data crossing the MCP boundary, in either direction, as trusted because it came from inside the system. In an agentic pipeline that assumption does not hold. That one sentence is the whole thesis. Everything below is evidence for it.
Google's MCP Toolbox for Databases ( googleapis/mcp-toolbox ) initialized its HTTP client without a CheckRedirect policy and without validating target IP addresses. A crafted path parameter could make the toolbox follow a redirect to an internal endpoint and send requests on the attacker's behalf. Google assigned CVE-2026-14540 with a CVSS score of 8.0. It was reserved on 3 July 2026 and published on 31 July. The CVE record credits me as finder.
The fix is the part I would point anyone to. PR #3448 checks resolved addresses at connection time, so DNS rebinding cannot swap the target between check and use. It applies IP-range allow and block lists. It rejects an unsafe base URL at startup instead of on first request. That is what a real SSRF guard looks like. It is also more work than most MCP servers have done.
JPMorgan Chase: a fork that dropped the check
JPMorgan's open-source jpmorgan-payments/ai repository includes a documentation- MCP server with two tools that fetch content. read_documentation applies a domain allowlist before fetching. Its sibling, related() , does not. It takes a caller-supplied URL and fetches it server-side with no restriction.
This is the finding I learned the most from, because nobody did anything obviously wrong. The component is forked from an AWS project. I diffed the two. AWS's original never dereferenced the caller's URL at all. JPMorgan's rewrite added the fetch and left out the allowlist. Two competent teams, one routine forking step, and a hole that neither codebase had on its own. No scanner flags that. You find it by reading both versions side by side.
JPMorgan Chase's Responsible Disclosure team confirmed the finding as valid, and a fix has been deployed. I am listed by name on JPMorgan Chase's public Responsible Disclosure recognition page (responsibledisclosure.jpmorganchase.com). It is medium severity. No credential travels with the forged request, so it does not reach the worst outcomes described below.
Weaviate merged a fix for an SSRF I reported. PR #12961 restricts the Google module's apiEndpoint , region , and location to Google API hosts. The finding is listed by name in Weaviate's public Security Hall of Fame, dated 25 August 2026.
Same pattern again. A configurable endpoint value decided where the server sent its outbound requests. The fix was to constrain it to the hosts the feature actually needs. By this point I was no longer surprised to find it. I was surprised when I did not.
France: DINUM and data.gouv.fr
DINUM, the French government's interministerial digital directorate, maintains datagouv/datagouv-mcp , the official MCP server for the national open-data platform. A URL field supplied by data producers was fetched server-side in a way that was open to DNS rebinding and could reach cloud metadata.
PR #126, titled "harden SSRF on external APIs," was merged on 4 September 2026. It opens with "Reported by Syed Anas Mohiuddin."
A national government's official server had the same bug as a bank's documentation tool. That is the kind of result the May hypothesis predicted and could not yet show.
Indonesia: Tangerang City government
The Tangerang City government in Indonesia maintains INFOKOM-KI/Wazuh-MCP-Server , an MCP server for automating security operations on Wazuh. Its blueteam_check_webshell tool advertised SSRF protection, but the check only rejected literal IP addresses. It never resolved hostnames, so any DNS name that pointed at a private, loopback, or link-local address, including cloud metadata, got through.
I reported it on 2 September 2026. The maintainers, who wrote back from a tangerangkota.go.id address, fixed it in commit 2bbfe12 and published GitHub advisory GHSA-pw2j-pj4h-f5vg on 3 September, rated high, with me credited as reporter. That is a day from my report to a published advisory.
A smaller data point, included for completeness. Rapid7's Bulk Export MCP server passed an export identifier into a GraphQL query without escaping it. Rapid7 published CVE-2026-97228 with a CVSS score of 2.7, Low, and credited me as finder.
It is not an SSRF and it is not severe. I include it because it is a different vendor, a security vendor at that, showing the same root behavior: a value crossing the MCP boundary went into a downstream request with no validation.
The cases above are the ones that best explain the pattern. They are a fraction of the work. As of today, 16 GitHub security advisories published by the projects' own maintainers credit me as reporter, and they cover more than SSRF: command injection, authentication gaps, session hijack, credential leaks, and bypasses of earlier fixes. Each link below is public and can be checked.
CakeRepository/1Password-MCP : 1Password MCP: a tool leaked the service-account token, defeating its own redaction.
CryptoAPIs-io/cryptoapis-mcp-hub : CryptoAPIs MCP hub: unauthenticated access spends the operator's API key.
datalayer/jupyter-mcp-server : Jupyter MCP server: Host-header spoof bypasses an earlier CVE fix.
IMRRD/powershell-mcp : powershell-mcp: WinRM password exposed in the OS process table.
INFOKOM-KI/Wazuh-MCP-Server : Wazuh MCP server (Tangerang City government): SSRF.
Repliers-io/mcp-server : Repliers MCP server: session IDs not bound to the caller, enabling session hijack.
SylphxAI/pdf-reader-mcp : pdf-reader-mcp: SSRF guard bypassable via DNS rebinding.
TMHSDigital/steam-mcp : steam-mcp: write tools with no confirmation gate.
VeriTeknik/pluggedin-app : pluggedin-app: OS command injection via MCP server arguments.
ark-forge/mcp-eu-ai-act : mcp-eu-ai-act: unauthenticated SSRF via a caller-supplied repo URL.
clidey/whodb : WhoDB MCP: read-only and confirmation gates allow privileged database file operations.
guimatheus92/mcp-video-analyzer : mcp-video-analyzer: SSRF with no host or IP allowlist.
navikt/copilot : navikt/copilot: OAuth server skipped redirect_uri validation.
timescale/mcp-boilerplate-node : mcp-boilerplate-node: reflected XSS via forwarded headers.
vitali87/code-graph-rag : code-graph-rag: shell allowlist bypass leading to command execution.
warpfreight/warp-agent-mcp : warp-agent-mcp: safety denylist wired into only 2 of 9 tools.
I have also had fixes merged in projects such as github-mcp-server, mongodb-mcp-server and salesforce-mcp-server. Several more reports are in triage with maintainers, and I am not counting those.
Governments: reported, open and unresolved
The second failure mode appeared in a cluster of MCP servers under GSA's Technology Transformation Services: a Department of Veterans Affairs benefits-claims server, a CMS Blue Button server, a regulations.gov server, a USASpending server, and a CDC PLACES server. I filed all five as private GitHub Security Advisories on 2 September 2026, and I am credited as reporter on each. All five are still in triage. They are not fixed, and I am not presenting them as confirmed outcomes.
The VA case shows the risk most clearly, so I will describe it only at the level of the class. When the upstream benefits API returns an error, the server logs the full upstream response body at ERROR level without redaction. Those bodies can contain a veteran's name, Social Security number, date of birth, and address. Routine validation failures are enough to trigger it, so every real deployment would produce these log entries during normal operation. I am leaving out code-level detail until it is patched.
Japan's Digital Agency ( digital-go-jp/jgrants-mcp-server ) is a similar open item. On 1 September 2026 I reported to JPCERT that the server had no authentication. On 7 September I opened a public pull request (#6) that requires an explicit opt-in to bind to anything other than loopback and caps attachment write size. The pull request has not been merged, and I am not presenting it as a confirmed outcome.
I am still an independent researcher. No institutional affiliation, no employer, no lab, no team. I found these bugs myself, wrote every report myself, and handled every disclosure myself, from first email to merged fix.
What has changed since May is who has checked the work. In May it was one public issue and my own argument. Since then, five separate security teams, at Google, JPMorgan Chase, Weaviate, DINUM, and the Tangerang City government, have each reviewed an SSRF finding of mine, confirmed it, and fixed it, and Rapid7 published a CVE for a related bug. Several of them put my name on the record. I think that is worth saying plainly, because it is the difference between a researcher with a theory and a researcher whose theory has been tested by the people with the most reason to dispute it.
Where this started: the May findings
The original writeup included Microsoft's playwright-mcp, which had the simplest version of the problem. Its browser_navigate tool accepted any URL the agent supplied, with no SSRF protection at all, so an agent could be steered to the AWS instance metadata service at 169.254.169.254 and its credentials. I filed this publicly as GitHub issue #1626. It is a public issue, not a vendor-confirmed finding. There is no CVE and no vendor confirmation, and the severity rating is my own assessment, not a vendor's.
That was the first example. The vendor-confirmed results above are what make the pattern hard to dismiss.
Taken alone, each of these is an ordinary web bug. They matter more because of where MCP servers sit. Real agent deployments chain protocols: MCP for tools, A2A for agent-to-agent delegation, ANP and others for discovery. Protocol Pivoting is what happens when an attacker who controls one node in that chain uses delegation semantics to cross trust boundaries.
A concrete case. An attacker places text in content that an MCP tool returns. The text is shaped like an A2A task instruction. The orchestrating agent reads the tool output and passes the instruction to a subagent as part of normal delegation. The subagent trusts its orchestrator, so it runs the instruction. If that subagent holds an MCP server with an SSRF, the request now originates inside the trust boundary, with the subagent's network position and permissions.
No single component was compromised in the classic sense. Each one behaved as designed. The formal writeup is at DOI 10.5281/zenodo.20371152 .
To be clear how the two pieces relate: Protocol Pivoting does not depend on SSRF. The scenarios in the paper work with any tool that gives an attacker an outbound or privileged action, such as a CRM write or an infrastructure call. SSRF is a separate, concrete bug class that I found in real MCP servers. It matters here because an unvalidated fetch is one of the easiest ways to give an attacker that outbound request from a privileged position, and that is why it keeps leading back to cloud metadata.
Why existing tooling does not see this
Software composition analysis and dependency scanners look for known-vulnerable packages and follow call graphs through code. In an MCP server, the dangerous input does not come through a code path those tools model. It comes over the transport, as a tool argument the model chose, described by a tool manifest the scanner never reads. The call graph stops at the transport boundary.
The redirect policy in Google's toolbox, the missing allowlist in JPMorgan's fork, and the full upstream response written to a federal server's logs all sit in code a dependency scanner would pass. None of the dependencies are vulnerable. The vulnerability is in how the server treats input it should not have trusted.
That is why I built mcp-safeguard (pypi.org/project/mcp-safeguard/), an open-source scanner that tests MCP servers through their exposed tool surface without needing source. It looks for six classes: SSRF, excessive permissions, prompt-injection surfaces, information leakage, authentication gaps, and lifecycle bypass.
It is a starting point, not a solution. Several of the findings above needed a human reading source and diffing forks, and pattern-matching tools, mine included, miss a large of this class. The honest claim is narrower. This layer needs to be checked, and right now it mostly is not.
What the pattern says
A hyperscaler, a global bank, an open-source database company, the French government, and a city government in Indonesia all wrote MCP servers independently, and the same SSRF mistake appears in all five. I have reported related issues in US federal servers and in Japan's Digital Agency too, but those are not yet confirmed. That is not individual carelessness. MCP makes it very easy to expose a function to an agent, and nothing in that path prompts the developer to ask who controls each argument, or what happens to the data coming back.
The fixes are not complicated. Validate resolved IPs at connection time, not before. Turn off automatic redirects or validate every hop. Apply the same allowlist to every tool that fetches, not just the first one written. Redact upstream bodies before logging them. Google's fix for CVE-2026-14540 is a good reference implementation.
On 23 October 2026 I will present this cross-vendor pattern at MCPCon North America in San Jose, including whichever findings are fixed by then. That talk is the May argument, five confirmations later.
I am still looking. MCP servers are being published faster than anyone is reviewing them, and the same two assumptions keep shipping with them. I am happy to technical material on any of the closed findings, walk through how any of them were found, or talk where this goes . The federal findings stay private until they are patched.
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
