MCP Go SDK CSRF: a web page can trigger your local tools (CVE-2026-33252)
The official MCP Go SDK accepted cross-site browser POSTs without checking the Origin header. On an unauthenticated local server, any website you visit could invoke your tools. Patched in 1.4.1.
What is this?
CVE-2026-33252 is a cross-site request forgery (CWE-352) flaw in the official Model Context Protocol Go SDK (github.com/modelcontextprotocol/go-sdk). The GitHub Security Advisory GHSA-89xv-2j6f-qhc8 was published March 19, 2026 and the CVE landed in the NVD on March 24, 2026, rated 7.1 (High). The fix shipped in v1.4.1; the vulnerability was reported by Lê Minh Quân.
The short version: before v1.4.1, the SDK’s Streamable HTTP transport accepted browser-generated cross-site POST requests without validating the Origin header and without requiring Content-Type: application/json. On a local MCP server running without authorization — a very common development and desktop-agent setup — any website the user happens to visit could send MCP requests to that server and potentially trigger tool execution. We are covering it because it is a clean, patched example of a systemic 2026 problem: local MCP servers treat the loopback interface as a trust boundary, and the browser quietly punches through it.
How it works
The browser’s same-origin policy normally stops a page on evil.example from reading responses from 127.0.0.1. But “simple” requests — those with a CORS-safelisted Content-Type such as text/plain — are sent without a CORS preflight. The attacker never needs to read the response; they only need the request to land.
Victim opens attacker page ──► fetch("http://127.0.0.1:<port>/mcp",
(in a normal browser) { method: "POST",
headers: { "Content-Type": "text/plain" },
body: <MCP JSON-RPC: tools/call ...> })
Local MCP server (pre-1.4.1):
- no Origin check ──► request accepted
- Content-Type not enforced ──► body parsed as MCP message
- no Authorization required ──► tool invoked
Because the server did not check where the request came from, a cross-site POST was indistinguishable from a legitimate local client. The impact is rated integrity-high, confidentiality-none (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:L): the attacker can cause actions (tool calls) but cannot directly read the reply across origins. The user-interaction requirement is just “visit a page.” No exploit payload is reproduced here — the mechanism is the lesson, and it is the same shape as ordinary web CSRF, applied to an agent’s tool layer.
This is not an isolated bug. The same missing-origin-validation pattern produced CVE-2026-34742 (DNS rebinding in the same Go SDK), CVE-2026-35568 (MCP Java SDK), and earlier CVE-2025-9611 in Microsoft’s Playwright MCP server. Different transports, same root cause — see our note on DNS rebinding against localhost MCP servers.
Why it matters
A local MCP server is rarely an empty toy. It is wired to a filesystem, a shell, a cloud CLI, a code repository, or a database — that is the point of giving an agent tools. When a website can reach that server and call those tools, the browser becomes an exfiltration and action channel into the host. The pre-conditions are mundane: the server binds to loopback, runs without auth (common for “it’s only on my machine” setups), and the developer browses the web in the same session. That combination describes a large fraction of agent developer workstations in 2026.
The broader takeaway for anyone shipping or operating MCP is that loopback is not authentication. 127.0.0.1 keeps remote network peers out, but it does nothing about the browser running on the same machine, which is a fully capable HTTP client pointed wherever an attacker’s page tells it to go. Pair that with the field data on MCP exposure — 40% of remote MCP servers run unauthenticated — and origin validation stops being a nicety.
Defenses
The patch is necessary but the architecture is what protects you.
-
Upgrade and turn the protection on. Move to go-sdk v1.4.1+ (which requires Go 1.25+). The fix adds
Content-Typevalidation for POST requests and a configurable origin check — enable it. RequireContent-Type: application/jsonand reject requests whoseOrigin/Hostdoes not match an allowlist of expected local values. -
Authenticate even on localhost. Do not run stateless, sessionless MCP servers without authorization. A bearer token or per-session secret that the browser cannot guess turns a drive-by tool call into a failed request.
-
Validate
Hostas well asOrigin. Host-header validation (rejecting anyHostthat is not your expected loopback value) is what neutralises the related DNS-rebinding variants — the server returns 403 even when the browser is tricked into hitting127.0.0.1. -
Treat the browser as an adjacent attacker. Network-isolate dev MCP servers, bind to a random high port, and gate high-impact tools (shell, file write, deploy, payments) behind explicit human approval. A confused-deputy tool call should hit a wall before it touches anything irreversible.
Status
| Item | Value |
|---|---|
| CVE | CVE-2026-33252 (GHSA-89xv-2j6f-qhc8) |
| Component | Official MCP Go SDK, Streamable HTTP transport |
| Affected | < 1.4.1 |
| Fixed | 1.4.1 (requires Go 1.25+); commit a433a83 |
| Severity | 7.1 High — CWE-352 (CSRF) |
| Disclosed | Advisory 2026-03-19 · NVD 2026-03-24 |
| Related | CVE-2026-34742 (Go DNS rebinding), CVE-2026-35568 (Java SDK), CVE-2025-9611 (Playwright MCP) |
Sources
- → https://vulnerability.circl.lu/vuln/cve-2026-33252
- → https://nvd.nist.gov/vuln/detail/CVE-2026-33252
- → https://github.com/modelcontextprotocol/go-sdk/security/advisories/GHSA-89xv-2j6f-qhc8
- → https://www.vulncheck.com/advisories/microsoft-playwright-mcp-server-dns-rebinding-via-missing-origin-header-validation