Three Advisories, No CVE, Zero Findings: The MCP SDKs Patched Redirects and npm audit Says You Are Fine

On 2 October 2026, within twelve minutes of each other, the Model Context Protocol reference SDKs published three security advisories through their own repositories. Two describe the same bug in two languages: HTTP client transports followed redirects to any origin, carrying custom headers and, on 307/308, the request body. The third says the TypeScript SDK’s experimental task store never checked which session created a task.

The engineering is unremarkable in the best way — the fixes are correct and the write-ups are unusually candid. What is worth your attention is everything that did not happen around them.

The three advisories

GHSA-6prh-2h8m-c8cw (TypeScript, medium, CVSS 3.1 6.5, CWE-200), published 2 October 2026 at 20:42:34Z. Affects @modelcontextprotocol/sdk all versions through 1.31.0 and @modelcontextprotocol/client 2.0.0 through 2.2.0. Fixed in 1.32.0 and 2.3.0.

GHSA-5h93-6whr-6q8j (Python, medium, CVSS 3.1 5.9, CWE-200), published 2 October 2026 at 20:42:25Z. Affects mcp 1.8.0 through 1.29.1 and 2.0.0 through 2.1.1. Fixed in 1.30.0 and 2.2.0.

GHSA-22jm-h49p-29qw (TypeScript, high, CVSS 3.1 8.6, CWE-639 and CWE-862), published 2 October 2026 at 20:54:41Z. Affects @modelcontextprotocol/sdk 1.24.0 through 1.31.0. Fixed in 1.32.0. The 2.x packages are not affected.

What the redirect bug actually exposes

The TypeScript advisory is specific about the material at risk. If an MCP server or authorization server redirected a request to another origin, that origin received custom request headers — the advisory names X-API-Key set through requestInit.headers — plus the mcp-session-id header. On a 307 or 308, which preserve the method and body, it also received the body, “including OAuth token requests with their refresh_token and client_secret.”

Both advisories note the one thing that was already safe: the runtime’s own fetch (and httpx on the Python side) already drops a bare Authorization header across origins. That is precisely the trap. The platform protects the one header everybody knows is sensitive, which makes the custom header carrying the same authority look protected by association. It was not.

The Python advisory adds the threat-model sentence that the TypeScript one leaves implicit, and it is the honest framing:

“Anyone able to make an endpoint you trust redirect elsewhere (a stale redirect to a lapsed domain, a misrouted proxy rule, redirect logic an attacker can influence) could capture that material. A server that is itself malicious gains nothing this way; it already receives your requests directly.”

That is why these are rated medium rather than high, and why both carry AC:H. This is not the malicious-server scenario that dominates MCP threat modelling. It is the lapsed domain scenario — the infrastructure decay case. An MCP endpoint you configured eighteen months ago still answers, still redirects, and the redirect target expired. We have written before about dead domains in the MCP server population; this is the client-side half of the same problem.

The task bug is the higher score, and the easier check

GHSA-22jm-h49p-29qw is the one to triage first: CVSS 8.6, and the exposure is cross-client rather than conditional on an unlucky redirect. In affected versions the experimental tasks feature did not check which session created a task, so “clients sharing one InMemoryTaskStore could list, read and cancel each other’s tasks.”

The advisory supplies the triage command itself, which is a courtesy more advisories should copy: if grep -ri taskstore --exclude-dir=node_modules . finds nothing, you are not affected. Only an HTTP server that passes taskStore to McpServer or Server is in scope.

The maintainers’ own recommendation is not to patch but to leave: “Experimental tasks are deprecated. The 2026-07-28 specification replaced them with a redesigned extension. The best course of action is to stop using them.” If you cannot upgrade, create one InMemoryTaskStore per session.

This is the third time the MCP ecosystem has shipped a task handler that forgot who owned the task — the Python SDK’s equivalent was CVE-2026-52870 (GHSA-hvrp-rf83-w775), published 5 June 2026, same class, different language. A feature marked experimental in two SDKs produced the same authorization omission in both.

Now the part that should worry you

We checked where these advisories are visible, and the answer is: almost nowhere.

  • No CVE. All three carry cve_id: null. They are repository-scoped advisories only.
  • Not in the global GitHub Advisory Database. Querying /advisories/GHSA-6prh-2h8m-c8cw, /advisories/GHSA-5h93-6whr-6q8j and /advisories/GHSA-22jm-h49p-29qw through the GitHub REST API returns 404 Not Found for each. They are readable only through the per-repository /security-advisories endpoint.
  • Not in OSV. https://api.osv.dev/v1/vulns/<ghsa> returns 404 for all three. For comparison, GHSA-345p-7cg4-v4c7 (CVE-2026-25536, the cross-client leak we covered in March) resolves in OSV normally.
  • Zero findings from the package manager. We created a project depending on @modelcontextprotocol/sdk at exactly 1.31.0 — a version inside the affected range of two of these advisories — and ran npm audit --json. Result: {"info":0,"low":0,"moderate":0,"high":0,"critical":0,"total":0}.

An OSV version query for @modelcontextprotocol/sdk 1.31.0, @modelcontextprotocol/client 2.2.0 and mcp 1.29.1 likewise returns zero vulnerabilities for each, though all three are named as affected by advisories published the same week.

Why this keeps happening to MCP specifically

This is now a documented pattern rather than an incident. We reported in September that two MCP command injections got CVEs and GHSAs that would never surface in npm audit — there because the advisories carried empty affected-package lists. Here the affected-package metadata is complete and precise; the advisories simply never left the repository.

The mechanisms differ, the outcome is identical: a security team whose process is “we watch the CVE feed and we run the package auditor” sees nothing, twice, for the reference implementation their entire agent stack depends on. And note the direction of the exposure in all three advisories: the client is vulnerable, not the server. MCP clients are the component least likely to be inventoried, scanned, or owned by anyone in particular. They are embedded in IDE extensions, internal tools and agent harnesses that nobody files a dependency review against.

To be fair to the maintainers: everything needed to act is published, in plain language, with per-case remediation and explicit statements about what the fix does not cover. The disclosure quality here is well above average. The distribution is what failed. An advisory that never reaches the databases your tooling queries is, operationally, a blog post.

One detail the release notes bury

The TypeScript 1.32.0 upgrade notes state that redirects are now followed only within the endpoint’s origin, “and not at all in browsers.” They also note that setting redirectPolicy: 'follow' on a transport restores the old behaviour and the exposure. The Python side carries the same shape of escape hatch, documented explicitly as unsupported.

This matters because the fix is breaking by design. The Python release notes are direct about it: if your client currently reaches its server through a cross-host redirect, “it will stop connecting after the upgrade.” The correct response is to set the endpoint URL to the redirect’s target. The tempting response, when a deploy breaks at 2am, is to flip the policy flag back — and silently reinstate the credential leak you just patched. Expect to find that flag in codebases a year from now.

What to do

  • Upgrade clients: @modelcontextprotocol/sdk to 1.32.0, @modelcontextprotocol/client to 2.3.0, mcp to 1.30.0 or 2.2.0. Servers and stdio clients are not affected by any of the three.
  • Grep for taskStore first. It is the highest-scored of the three and takes one command to rule out. If it is present, prefer removing it — the feature is deprecated, not merely buggy.
  • Rotate what may have travelled. Both redirect advisories say it plainly: if a redirect may have reached a host you do not control, rotate the API keys and client_secret the application held and revoke its tokens. Rotation is cheap; reconstructing six months of redirect history is not.
  • If you cannot upgrade yet, the stated workarounds are a fetch that refuses redirects (redirect: 'error') on the TypeScript side, and an HTTP client with follow_redirects left at its default False on the Python side.
  • Audit the escape hatches in review. Add redirectPolicy: 'follow' and any follow_redirects=True on an MCP transport to whatever your linter or code-review checklist flags. These are now load-bearing security settings with innocuous names.
  • Do not rely on scanners for MCP SDK exposure. Watch the repositories’ own /security-advisories endpoints directly. For the three repos that matter, that is three API calls you can run on a schedule — and on current evidence it is strictly more coverage than your SCA tool provides.

Our verification was primary-source-led. We read all three advisories through the GitHub REST API from the modelcontextprotocol/typescript-sdk and modelcontextprotocol/python-sdk repository advisory endpoints, and quote their published severities, CVSS vectors, CWE identifiers, affected ranges, publication timestamps and remediation text as returned. We confirmed the absence of each GHSA from the global GitHub Advisory Database and from OSV by direct API lookup, and confirmed that a known-published MCP advisory (GHSA-345p-7cg4-v4c7) resolves in both for contrast. We verified release dates and version numbers against the npm registry and PyPI metadata, and read the 1.32.0, v1.30.0 and v2.2.0 release notes from the GitHub releases API. The npm audit result was produced locally against a lockfile pinning @modelcontextprotocol/sdk 1.31.0; we report its JSON summary verbatim. No CVE has been assigned to any of the three advisories at the time of writing, and we do not imply one. We did not exploit, or attempt to exploit, any of these issues.

Sources: