MCP TypeScript SDK CVE-2026-111769
MEDIUMAttack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessLure client to malicious or compromised MCP/auth server
-
DeliveryServer returns 307/308 cross-origin redirect
-
ExploitClient auto-follows and re-sends headers and body
-
ExecutionAttacker origin captures X-API-Key, client_secret, refresh_token
-
ImpactReuse stolen credentials and tokens
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V14 - Data Protection Data exposure prevention
MITRE ATT&CK
2 techniques across 2 tactics: Collection, Discovery The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | The application must use @modelcontextprotocol/sdk (<1.32.0) or @modelcontextprotocol/client (2.0.0-2.2.0) via StreamableHTTPClientTransport, SSEClientTransport, or OAuth client functions such as auth(); stdio clients are explicitly not affected. Actual exposure requires the connected MCP server or authorization server to issue a cross-origin redirect toward an origin the attacker controls or can observe - i.e. a malicious/compromised server endpoint or a network MITM position - so a client talking only to a trusted first-party server over TLS is not practically exploitable. Header leakage (X-API-Key, mcp-session-id) occurs on any followed redirect, but body/secret leakage (refresh_token, client_secret) requires a method-preserving 307 or 308 redirect. Limiting factors: modern fetch already drops the Authorization header across origins; browser runtimes never expose redirect targets so the request simply fails there; and in fixed versions the vulnerable behavior only returns if an operator explicitly sets redirectPolicy: 'follow'. |
| Impact | This is a moderate-severity information-disclosure flaw (CWE-200) in the Model Context Protocol TypeScript client SDK, where HTTP transports and OAuth helpers followed redirects to any origin, leaking custom headers (e.g. X-API-Key), the mcp-session-id, and - on 307/308 - the request body including OAuth refresh_token and client_secret. The vendor CVSS vector (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N = 6.5) is internally consistent and credible: network vector and no client-side authentication (PR:N), but high attack complexity (AC:H) because exploitation is not self-contained - it requires the MCP server or authorization server the client connects to issue a cross-origin redirect toward an attacker-observable origin, meaning the attacker must control/compromise that server endpoint or hold a network MITM position. No EPSS score, KEV listing, POC, or SSVC decision data was supplied, so exploitation probability cannot be quantified from the input: no public exploit identified at time of analysis. The realistic priority is elevated for organizations building MCP clients that connect to third-party or untrusted MCP/authorization servers (credential and token theft is directly enabled), but lower for clients that only talk to fully-trusted first-party servers over TLS. This is a genuine credential-exposure bug rather than a high-CVSS-but-hollow issue, yet its real-world urgency is tempered by the AC:H precondition and the mitigating fact that modern fetch already strips the Authorization header cross-origin. |
| Exploit ScenarioDerived | An application using StreamableHTTPClientTransport, SSEClientTransport, or the SDK's OAuth auth() helpers connects to a malicious or compromised MCP/authorization server (or an attacker performs a MITM on the connection). The server responds with a 307/308 redirect to an attacker-controlled origin, and the vulnerable client automatically re-sends its custom headers and request body - handing over X-API-Key, mcp-session-id, and OAuth refresh_token/client_secret. No public exploit code was identified in the provided data, but the technique is straightforward once an attacker controls a redirect target. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv1 – Oct 20, 2026
Cross-origin redirect following in the Model Context Protocol TypeScript client SDK lets a malicious or compromised MCP server or OAuth authorization server receive credentials the client intended for a different origin: custom headers such as X-API-Key and mcp-session-id on any followed redirect, plus full request bodies containing OAuth refresh_token and client_secret values when the redirect uses a method-preserving 307 or 308. The flaw (CWE-200) affects @modelcontextprotocol/sdk through 1.31.0 and @modelcontextprotocol/client 2.0.0 through 2.2.0, and only applications using StreamableHTTPClientTransport, SSEClientTransport, or the SDK's OAuth helpers such as auth() are exposed - stdio clients are not; extraction of the CVSS 6.5 score requires remote, unauthenticated reachability but high attack complexity, since real exposure depends on the client being steered to a cross-origin redirect by an untrusted or intercepted endpoint. No public exploit code and no confirmed active exploitation were identified at time of analysis, and modern fetch runtimes already strip the Authorization header across origins, which limits the blast radius somewhat.
RemediationAI
Vendor-released patch: upgrade to @modelcontextprotocol/sdk 1.32.0 or later on the 1.x line, or @modelcontextprotocol/client 2.3.0 or later on the 2.x line, as documented in GHSA-6prh-2h8m-c8cw (https://github.com/modelcontextprotocol/typescript-sdk/security/advisories/GHSA-6prh-2h8m-c8cw); the fixes landed in pull requests https://github.com/modelcontextprotocol/typescript-sdk/pull/2901 and https://github.com/modelcontextprotocol/typescript-sdk/pull/2902. After upgrading, redirects are followed only within the same origin and not at all in browsers, so deployments whose MCP server or authorization server legitimately bounces to a different origin must configure the transport with the final post-redirect URL instead of relying on the redirect chain - resisting the temptation to set redirectPolicy: 'follow', which restores the old behavior and the credential exposure. If an upgrade cannot be shipped immediately, supply a fetch implementation that refuses redirects, e.g. (url, init) => fetch(url, { ...init, redirect: 'error' }), passed into the transport and OAuth call sites; the trade-off is that any legitimate redirect (including well-known metadata discovery fallbacks) will now hard-fail, which may require pointing clients directly at canonical endpoints. Assume compromise for any client that may have followed a cross-origin redirect to a host you do not control: rotate the API keys and client_secret values the application held and revoke its issued tokens, since tokens and secrets delivered over the leaked body cannot be recalled. Restricting outbound egress from client hosts to known MCP and authorization server endpoints is a useful secondary control that shrinks the set of reachable redirect targets.
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 2 packages in npm
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
The MCP TypeScript client SDK implements the client half of the Model Context Protocol over HTTP using two transports, StreamableHTTPClientTransport and SSEClientTransport, plus an OAuth client layer that performs protected-resource metadata discovery, authorization-server metadata discovery, dynamic client registration, token exchange and refresh, and JWT authorization grant flows. All of these issued their HTTP requests through the platform fetch implementation with default redirect handling, so a 301/302/303/307/308 response from the connected server was transparently followed to whatever origin the Location header named. Because fetch only strips the Authorization header on cross-origin hops, the additional material attached by the SDK - arbitrary caller-supplied headers from requestInit.headers (an X-API-Key, for example) and the mcp-session-id session correlator - was replayed to the new origin, and on 307/308 the request body was re-sent as well, exposing OAuth refresh_token and client_secret fields. This is an information-disclosure weakness (CWE-200) rooted in missing origin validation on redirect, not an injection or memory-safety defect. The upstream fix introduces a fetchWithinOrigin wrapper (with companion helpers fetchLeavingRedirects and unfollowedRedirect) applied across the SSE/Streamable HTTP code paths and the auth module functions discoverOAuthProtectedResourceMetadata, executeTokenRequest, registerClient, requestJwtAuthorizationGrant and exchangeJwtAuthGrant. The new policy follows a redirect only when scheme, host and port are unchanged (or an http-to-https upgrade on the same host with default ports) and the method is preserved (307/308, or any redirect of a GET), caps Node-side same-origin chains at five, fails the request with a named target otherwise while keeping the session reusable, and advances OAuth metadata discovery to the next well-known URL instead of following the hop. In browsers, where redirect targets are not exposed to the page, redirected requests simply fail. A new redirectPolicy: 'follow' transport option restores the legacy behavior and re-introduces the exposure, while requestInit.redirect values of 'error' or 'manual' are now honored for transport-level POST/GET/DELETE traffic.
Know when the next one hits your stack
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N
Exploitation needs an attacker-controlled cross-origin redirect from the connected server, so AC:H; no client-side auth gives PR:N; leaked client_secret/refresh_token/API keys give C:H with minor I:L and no availability impact.
Primary rating from GitHub Advisory.
CVSS VectorGitHub Advisory
DescriptionGitHub Advisory
Summary
In affected versions, the SDK's HTTP client transports and OAuth requests followed redirects to any origin.
If an MCP server or authorization server redirected a request to another origin, that origin received custom request headers (such as an X-API-Key set in requestInit.headers) and the mcp-session-id header. On a 307 or 308 it also received the request body, including OAuth token requests with their refresh_token and client_secret.
On current runtimes fetch already drops the Authorization header across origins.
Am I affected?
Yes, if your application uses StreamableHTTPClientTransport, SSEClientTransport, or the SDK's OAuth client functions such as auth(). stdio clients are not affected.
Affected versions:
@modelcontextprotocol/sdkall versions through 1.31.0@modelcontextprotocol/client2.0.0 through 2.2.0
Fix
Upgrade to:
- 1.x:
@modelcontextprotocol/sdk1.32.0 or later - 2.x:
@modelcontextprotocol/client2.3.0 or later
Redirects are now followed only within the same origin, and not at all in browsers. If your MCP server or authorization server redirects to another origin on purpose, configure the final URL instead. Setting redirectPolicy: 'follow' on a transport restores the old behaviour and the exposure.
If a redirect may have reached a host you do not control, rotate the API keys and client_secret your application held and revoke its tokens.
If you cannot upgrade yet, pass a fetch that refuses redirects, for example (url, init) => fetch(url, { ...init, redirect: 'error' }).
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
GHSA-6prh-2h8m-c8cw
NVD
CVE.org
Exploit-DB