The October Redirect Advisory Got a CVE and Brought Two Siblings: Three Flaws in MCP Python SDK 1.30.0
On 27 October 2026 three GitHub-reviewed security advisories landed against the Model Context Protocol Python SDK, all fixed in mcp 1.30.0 and 2.2.0. One is familiar: the cross-origin redirect credential leak disclosed without a CVE on 2 October now has one — CVE-2026-116685 (GHSA-5h93-6whr-6q8j, 5.9 medium). The other two are new, and the worse of them is the one to patch first: CVE-2026-116684 (GHSA-w4fh-qvv9-3v23, 6.8 medium), where server-side bearer authentication accepted tokens issued for a different resource server, and CVE-2026-116686 (GHSA-rwrf-2pqf-9j8j, 6.5 medium), where a connected server could make the client fetch attacker-chosen URLs — or read local files — during tool-result validation and freeze every session in the process.
CVE-2026-116684 is the authorization bug, and its honesty is refreshing: the SDK’s server-side bearer authentication had no way to check a token’s audience at all. Where one authorization server issues tokens for several services, a valid token for another service was accepted by your MCP server (CWE-863, CVSS 6.8, attack complexity high, privileges low). Affected: mcp 1.10.0 through 1.29.1 and 2.0.0 through 2.1.1. The fix is a two-step migration, and the advisory is explicit that upgrading alone changes nothing: patched versions add a validate_token_resource setting that stays off unless you set it. You must set validate_token_resource=True with resource_server_url matching the audience your authorization server mints for your server, and return the token’s audience from verify_token() as AccessToken.resource — set only the flag and every request 401s. If your TokenVerifier already checks aud itself, set the flag to False to silence the deprecation warning; it defaults to True in 3.0. If you cannot upgrade yet, the advisory gives the backportable workaround: reject any token whose aud does not include your server inside verify_token().
CVE-2026-116686 is the one that should worry client deployers. When a connected server declared an outputSchema for a tool, the SDK validated each call_tool result with jsonschema’s default resolver — which fetches any $ref it cannot resolve locally by opening the URL. A server could embed an http://, https:// or file:// reference and make the client request that URL or read that local file from the client’s own network position on every call of the tool (CWE-918 SSRF). Two mitigations blunt the worst readings: the fetched content was used only as a schema and never sent back to the server, so this is a blind probe-and-read primitive, not exfiltration — and exploitation needs the user to actually call the tool (UI:R). But the availability half is unblunted: the fetch ran synchronously on the event loop with no timeout, so a target that accepted the connection and went quiet froze every session in the process for as long as it held the connection. A malicious or compromised MCP server turns into a client-side denial of service with one schema. Affected: mcp 1.10.0 through 1.29.1 and 2.0.0 through 2.1.1; upgrade to 1.30.0/2.2.0 with no extra configuration required.
CVE-2026-116685, the returning sibling, keeps the shape we described on 2 October: the Streamable HTTP and SSE client transports followed redirects to any host, sending custom headers (say, an X-API-Key) and, on 307/308, the request body to the redirect target, with the SDK’s OAuth providers repeating the mistake on discovery, registration and token requests. The lone Authorization bearer header was never exposed — the HTTP library drops it cross-origin — which is precisely the trap: the one header everyone knows is sensitive was safe, and the custom header carrying equal authority was not. Affected: everything from 1.8.0; fixed in 1.30.0/2.2.0. What changed since our earlier briefing is status, not mechanics: it is now a CVE in the reviewed advisory database, which means scanners that missed it on 2 October — we demonstrated npm audit finding zero — should now fire. If you suppressed or deferred the October advisory for lack of a CVE identifier, the excuse has expired.
Why defenders should take this seriously — and where to discount it
The serious part is the pattern, not any single score. Three mediums in one release, spanning client auth, client transport, and server auth, in the reference SDK that the ecosystem copies — this is the MCP trust model being audited in public, one layer at a time, and the layers keep failing open. The 116684 opt-in deserves emphasis: a fix that requires two coordinated code changes and ships off by default will have a long tail of “upgraded but still vulnerable” deployments, exactly the shape we saw in the TypeScript SDK’s five-CVE batch with its off-by-default regression. The discount: none of these is remotely exploitable at scale without preconditions — shared authorization servers without audience checks, attacker-influenced redirects, a malicious or compromised MCP server the victim already uses. These are hardening-grade flaws in a young protocol, not KEV candidates. Patch on your normal SDK-upgrade cadence, but do the 116684 second step — an upgrade without validate_token_resource is security theater for that CVE.
What it means for builders and defenders
- Upgrade mcp to 1.30.0 (1.x) or 2.2.0 (2.x), then finish the 116684 migration. Set
validate_token_resource=Trueplusresource_server_urland return the audience fromverify_token()— verify with a token minted for a different service and confirm you get a 401. Audit for “upgraded but flag off” instances; they are still vulnerable. - Treat MCP servers as SSRF-capable input after 116686. If your client talks to third-party or user-configured servers, the pre-1.30.0 client would fetch URLs and read local files on a server’s say-so and could be frozen by a silent endpoint. Post-upgrade, keep output-schema validation in mind as residual attack surface in your threat model.
- Re-run the scanners that were blind on 2 October. The redirect advisory now carries CVE-2026-116685 in reviewed databases feeding OSV, GitLab and scanner feeds. If your policy gates on CVE identifiers, the finding should now appear — confirm it does rather than assuming the feed updated.
- Watch the TypeScript twin. The October redirect pair shipped in both SDKs; the audience-bypass and
$ref-fetch patterns are the kind of bug that rhymes across implementations. Check the TypeScript SDK’s running advisory count before assuming the other half of your stack is clean.
Our verification was read-only. All three advisories — CVE-2026-116684/GHSA-w4fh-qvv9-3v23 (6.8, CWE-863, 1.10.0–1.29.1 and 2.0.0–2.1.1, fix 1.30.0/2.2.0, opt-in validate_token_resource migration, PRs 3447/3451), CVE-2026-116685/GHSA-5h93-6whr-6q8j (5.9, CWE-200, from 1.8.0), CVE-2026-116686/GHSA-rwrf-2pqf-9j8j (6.5, CWE-918, from 1.10.0), all published 27 October 2026 — were read first-hand via OSV and the GitLab Advisory Database mirrors of the GitHub-reviewed records, including affected ranges, fix versions, and the verbatim threat-model and migration notes quoted above. No SDK was installed, no token was minted, no redirect or schema payload was tested, and all interpretation above is ours. Brave Search was used for discovery only.
Sources:
- OSV — GHSA-w4fh-qvv9-3v23 / CVE-2026-116684 (reviewed record read first-hand; summary, severity, affected ranges, fix versions, migration guidance, fix commits)
- GitLab Advisory Database — CVE-2026-116685 / GHSA-5h93-6whr-6q8j (mirror of reviewed record read first-hand; redirect behavior, OAuth provider scope, affected and fixed versions)
- GitLab Advisory Database — CVE-2026-116686 / GHSA-rwrf-2pqf-9j8j (mirror of reviewed record read first-hand; $ref fetch behavior, file:// read, event-loop freeze, affected and fixed versions)
- al-ice.ai — Three advisories, no CVE, zero findings (the 2 October briefing on the redirect pair and the scanner gap)
- al-ice.ai — The official SDK needed four fixes at once (the off-by-default precedent on the TypeScript side)