Cve 2026 104850 · AI Security

MCP TypeScript SDK Lets a Malicious Server Pull OAuth Secrets From Clients (CVE-2026-104850)

Data graphic: the MCP TypeScript SDK flaw CVE-2026-104850, CVSS 3.1 score 7.5 High, fixed in 1.31.0 and 2.2.0
OP

AI security researcher · Updated Oct 6, 2026, 9:31 PM EDT

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.

Data graphic: affected and fixed versions of @modelcontextprotocol/sdk 1.12.0 to below 1.31.0 and @modelcontextprotocol/client 2.0.0 to below 2.2.0

Affected and fixed versions for the two npm packages.

Who is affected

  • @modelcontextprotocol/sdk 1.12.0 up to but not including 1.31.0
  • @modelcontextprotocol/client 2.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_token and client_secret saved from an earlier sign-in
  • on 1.x and 2.x, the configured client_secret or 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

  1. Upgrade to the current release: @modelcontextprotocol/sdk 1.32.1 or @modelcontextprotocol/client 2.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/core to 2.2.0 or later (current: 2.3.1) if you import it directly.
  2. Upgrading alone is not enough, as with the Python SDK. Set expectedIssuer on bundled providers, and add an issuer to credentials stored before the upgrade or clear them so users sign in again. Custom OAuthClientProvider implementations must persist the issuer.
  3. 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() or exchangeAuthorization(), or 2.x clients with skipIssuerMetadataValidation: true.
  4. 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.
  5. 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/sdk 1.12.0, where the affected range starts (npm).
  • 27 July 2026: @modelcontextprotocol/client 2.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.

Sources