CVE-2026-104850 lets a malicious MCP server make the TypeScript SDK's OAuth client send refresh tokens and client secrets to an attacker's server. Fixed in 1.31.0 / 2.2.0.
The official MCP TypeScript SDK has the same class of OAuth flaw ThreatFrontier covered in the Python SDK. A malicious or compromised MCP server can make a client send stored OAuth credentials to an authorization server the attacker chose. The user does not have to do anything. What is new here compared with our Python coverage: the fix has gaps, 2.x users also need the core package, and the packages are downloaded tens of millions of times a week. CVE-2026-104850 is rated CVSS 3.1 7.5 High by the GitHub CNA. It is fixed in @modelcontextprotocol/sdk 1.31.0 and @modelcontextprotocol/client 2.2.0.
Affected and fixed versions for the two npm packages.
Who is affected
@modelcontextprotocol/sdk1.12.0 up to but not including 1.31.0@modelcontextprotocol/client2.0.0 up to but not including 2.2.0
An application is exposed if it uses the SDK's OAuth client over HTTP (an authProvider on a transport, the withOAuth() middleware, or direct calls to auth() or fetchToken()) and may connect to an MCP server it does not fully trust while holding credentials for a legitimate authorization server. The bundled providers are ClientCredentialsProvider, PrivateKeyJwtProvider, StaticPrivateKeyJwtProvider and, in 2.x, CrossAppAccessProvider. MCP servers built with the SDK and stdio clients are not affected.
On 2.x the exposure is narrower: bundled providers without expectedIssuer, credentials stored or supplied without issuer, direct fetchToken() calls, and providers that read storage back through OAuthTokensSchema or OAuthClientInformationSchema.
What goes wrong
During OAuth discovery, an MCP server publishes protected resource metadata that names its authorization server. The SDK trusted that choice. Stored and pre-provisioned credentials were not bound to the authorization server they came from. A hostile server could therefore name its own authorization server in that metadata, and the client would send it:
- on 1.x, the
refresh_tokenandclient_secretsaved from an earlier sign-in - on 1.x and 2.x, the configured
client_secretor signed assertion of a bundled non-interactive provider
NVD lists the weaknesses as CWE-345 and CWE-522. The vector is network, low complexity, no privileges, no user interaction, with high confidentiality impact only.
Exploitation status
The CISA coordinator entry in NVD (2026-10-06) records exploitation as "none" and automatable as "yes". The CVE is not in the CISA KEV catalog (we checked the feed released 2026-10-04), and we found no report of in-the-wild use. NVD's own analysis is still pending.
What to do
- Upgrade to the current release:
@modelcontextprotocol/sdk1.32.1 or@modelcontextprotocol/client2.3.1 (both released 5 October 2026). The minimum fixed versions are 1.31.0 and 2.2.0. On 2.x, also move@modelcontextprotocol/coreto 2.2.0 or later (current: 2.3.1) if you import it directly. - Upgrading alone is not enough, as with the Python SDK. Set
expectedIssueron bundled providers, and add anissuerto credentials stored before the upgrade or clear them so users sign in again. CustomOAuthClientProviderimplementations must persist the issuer. - Know what the fix leaves open. Per the advisory, it does not cover new interactive sign-ins, which still use the server-named authorization server. It also does not cover direct calls to
refreshAuthorization()orexchangeAuthorization(), or 2.x clients withskipIssuerMetadataValidation: true. - If you cannot upgrade, 1.x has one workaround: connect OAuth-enabled clients only to MCP servers you trust (see our explainer on the agent control plane for brokering credentials at the tool call). Versions 2.0.0 and 2.1.0 already accept
expectedIssuer. - If an affected client may have connected to an untrusted MCP server, the advisory says to rotate its client secret or signing key and revoke its tokens (the Python SDK article covers the same steps).
Timeline and scale
- 22 May 2025:
@modelcontextprotocol/sdk1.12.0, where the affected range starts (npm). - 27 July 2026:
@modelcontextprotocol/client2.0.0, where its affected range starts (npm). - 28 September 2026: fixed releases 1.31.0 and 2.2.0.
- 30 September 2026: GitHub advisory published.
- 6 October 2026: NVD record published.
npm shows 76,226,448 downloads of @modelcontextprotocol/sdk, 7,366,290 of @modelcontextprotocol/client and 12,553,353 of @modelcontextprotocol/core for 28 September to 4 October 2026. Downloads are not exposed applications. Only OAuth clients over HTTP that connect to untrusted servers are affected; servers and stdio clients are not.
Credit
The advisory lists as reporters Aviral2642, AlexMelanFromRingo, Gal3m, JosephDoUrden, Igfray, OriginalKazdov and lwebmedia.