Vulnerability disclosure write-up CVE-2026-14540

I found an SSRF in Google's official MCP Toolbox

CVE-2026-14540. CVSS 8.0. Credited by name in Google's fix. But the interesting part isn't the bug — it's why the industry's standard dependency-scanning tools can't see this class of vulnerability at all.

Anas Mohiuddin Syed · Independent Researcher, Chicago, IL
anasmohiuddinsyed@gmail.com · github.com/syedanas01

In July, Google assigned CVE-2026-14540 for a server-side request forgery in their MCP Toolbox for Databases. The HTTP client was initialized without a CheckRedirect policy and without target IP validation, so a crafted path parameter could redirect the toolbox into making requests to internal endpoints on behalf of whoever controlled the prompt.

I found it with a scanner I wrote in a weekend.

8.0CVSS score
Fixedcredited by name

That's the actual story here, and it's not really a story about my scanner. It's that a new class of dependency — the MCP tool server — has appeared inside production systems at companies like Google, and the tooling the industry uses to find vulnerabilities in dependencies doesn't see it.

Why existing tooling misses this

Software composition analysis works by building a call graph from application code and asking whether a vulnerable function is reachable from it. That question is well posed for a library you import. It is not well posed for an MCP server.

An MCP server is invoked over stdio or HTTP via JSON-RPC. The application doesn't call the server's functions directly; it sends it a message. The call graph stops at the transport boundary, so a reachability engine sees nothing on the other side.

Two consequences follow, and they're the interesting part:

The edge isn't missing, it's in a different artifact. A server's tools/list response enumerates exactly the callable entry points and their JSON schemas. The analysis has to be two-sided, joined by the manifest rather than by one graph: resolve which tools a deployment actually exposes, then use those handlers as roots inside the server.

The caller is a model, which breaks the usual argument. Whether a function executes in a normal program is decidable from the code. Whether a tool executes is decided at runtime by a model conditioned on input an attacker may partly control. The conservative — and I think correct — position is that for MCP, exposure equals reachability. Anything in the served manifest should be assumed reachable, with reachability reduced only by controls outside the model (allowlists, scopes, human confirmation), not by distance in a call graph.

What the scanner actually does

mcp-safeguard, on PyPI, DOI-archived on Zenodo. CVSS-scored static-analysis rules over tool manifests and handlers: unvalidated redirect targets and SSRF, injection through tool descriptions, allowlist/denylist bypass patterns, over-broad tool permissions and credential exposure.

It is not clever. That's the point. The rules are boring, and one of them found a CVSS 8.0 in Google's toolbox because this dependency class has had almost no adversarial attention relative to how fast it's being deployed.

Disclosure timeline

DateEvent
2026-07-03CVE-2026-14540 reserved by Google
2026-07-31Published, CVSS 8.0, fixed in googleapis/mcp-toolbox PR #3448, credited by name
Coordinated disclosure throughout. Nothing here was published ahead of the vendor. The fix implements a real SSRF guard with DNS-rebinding/TOCTOU protection, IP-range allow/block lists, and fail-fast base-URL validation — substantive remediation, not a cosmetic patch.

What I think happens next

The number of MCP servers in production is growing much faster than the number of people looking at them adversarially. This finding wasn't hard. It was unlooked-for.

I'm running the scanner across every public MCP server I can enumerate. If you maintain one and want it looked at before I publish anything broader, email me and I'll send you findings privately first.