Skip to main content

MCP TypeScript SDK EUVDEUVD-2026-93491

| CVE-2026-104850 HIGH
Insufficient Verification of Data Authenticity (CWE-345)
2026-10-06 https://github.com/modelcontextprotocol/typescript-sdk GHSA-6qxp-vccf-f47h
7.5
CVSS 3.1 · Vendor: https://github.com/modelcontextprotocol/typescript-sdk
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Operate malicious or compromised MCP server
  2. Delivery
    Victim client connects holding stored OAuth credentials
  3. Exploit
    Server advertises attacker-controlled authorization server
  4. Execution
    SDK sends refresh_token and client_secret
  5. Impact
    Attacker captures and replays stolen credentials

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A08:2025 - Software or Data Integrity Failures
ASVS 5.0
V15 - Secure Coding and Architecture Data authenticity verification
Exploitation Conditions

Exploitation requires ALL of: (1) the application uses the SDK's OAuth client over HTTP via an authProvider on a transport, the withOAuth() middleware, or direct auth()/fetchToken() calls; (2) it holds credentials for a legitimate authorization server (a stored refresh_token/client_secret, or a bundled provider's client_secret/signed assertion); and (3) it connects to an MCP server the operator does not fully trust. For @modelcontextprotocol/client 2.x the window is narrower - only bundled providers (ClientCredentialsProvider, PrivateKeyJwtProvider, StaticPrivateKeyJwtProvider, CrossAppAccessProvider) constructed WITHOUT expectedIssuer, credentials stored/supplied WITHOUT issuer, direct fetchToken() calls, or custom providers reading storage back through OAuthTokensSchema/OAuthClientInformationSchema. Limiting factors that reduce real-world exposure: stdio clients are NOT affected, MCP servers built with the SDK are NOT affected, and the trigger depends on the victim choosing to connect to an untrusted server rather than a purely attacker-initiated reach. Note residual risk even after upgrade: a fresh interactive sign-in, and credentials persisted without an issuer before upgrading, still go to whichever authorization server the MCP server names until issuer is added or the credentials are cleared; skipIssuerMetadataValidation:true on 2.x also defeats the fix.

Impact

This is a credential-disclosure flaw (CWE-345, Insufficient Verification of Data Authenticity) in the MCP TypeScript SDK's OAuth client, rated CVSS 7.5 with vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - pure confidentiality impact, no integrity or availability loss, which directly contradicts the single input Tag 'Denial Of Service'. No EPSS score was provided, so exploitation-probability cannot be quantified from this data. The CVE is NOT in CISA KEV and no public exploit code is referenced, so this is no public exploit identified at time of analysis - not active exploitation. The network vector and lack of required interaction make the mechanism trivial once triggered, but real-world risk is gated by a meaningful precondition the CVSS vector understates: the victim client must already hold valid OAuth credentials AND voluntarily connect to an MCP server the operator does not fully trust. This is therefore a genuine priority for the specific population of applications using the SDK's HTTP OAuth client against semi-trusted servers (where leaked refresh_tokens, client_secrets, or signed assertions enable downstream impersonation against the legitimate authorization server), but closer to a moderate, conditional risk than a mass-exploitable internet-facing bug for the general population. Key missing signals: no EPSS, no KEV confirmation, no POC evidence - absence noted explicitly, not treated as safety.

Exploit ScenarioDerived

An attacker stands up (or compromises) an MCP server and lures a victim application - one using the SDK's OAuth client over HTTP while holding credentials for a legitimate authorization server - into connecting to it. With no user interaction, the attacker's server advertises its own authorization server and the SDK sends the stored refresh_token and client_secret (or a bundled provider's client_secret/signed assertion) to the attacker-controlled endpoint, which the attacker then replays against the real authorization server. No public exploit code is referenced, but the network vector and low attack complexity make the credential-theft step straightforward once a connection is established.

This Week Schedule remediation this week. Why: HIGH severity (CVSS 7.0-8.9).
Patch available 0.2% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 06, 2026

Credential disclosure in the MCP TypeScript SDK OAuth client (npm @modelcontextprotocol/sdk 1.12.0 through 1.30.1, and @modelcontextprotocol/client 2.0.0 through 2.1.0 in narrower configurations) lets a malicious or compromised MCP server direct the client's stored OAuth credentials to an authorization server of the attacker's choosing. Because saved credentials were never bound to the authorization server that issued them, a remote, unauthenticated attacker who controls or compromises the MCP server the victim connects to can silently receive a stored refresh_token and client_secret - or a bundled provider's client_secret or signed assertion - yielding full confidentiality impact (CVSS 3.1 7.5, AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N, per the PR:N vector the request is unauthenticated). No public exploit code and no confirmed active exploitation were identified at time of analysis; exploitation requires the victim application to use the SDK's OAuth client over HTTP and to connect to an MCP server it does not fully trust while holding credentials for a legitimate authorization server.

RemediationAI

Vendor-released patch: upgrade to @modelcontextprotocol/sdk 1.31.0 or later for the 1.x line, or @modelcontextprotocol/client 2.2.0 and @modelcontextprotocol/core 2.2.0 or later for the 2.x line, per the fix references https://github.com/modelcontextprotocol/typescript-sdk/pull/2887 and commit edd12e282620ebf770d67316f19cf91d4112a1bd. Upgrading alone is insufficient in three cases: bundled providers (ClientCredentialsProvider, PrivateKeyJwtProvider, StaticPrivateKeyJwtProvider, CrossAppAccessProvider) must be constructed with expectedIssuer set to the authorization server's issuer (e.g. expectedIssuer: 'https://auth.example.com'), otherwise they still follow whichever authorization server the MCP server names; any credentials persisted without an issuer - including everything 1.x saved before 1.31.0 - must have the issuer added or be cleared so users re-authenticate, since those credentials otherwise still travel to the first authorization server named; and custom OAuthClientProvider implementations must persist exactly what saveTokens()/saveClientInformation() receive, including issuer, and return issuer in clientInformation() for pre-registered credentials. If an affected client may have connected to an untrusted MCP server, rotate its client secret or signing key and revoke its tokens. Residual gaps not covered by the fix: a fresh interactive sign-in still goes to the authorization server named by the MCP server (only complete sign-ins for trusted servers, which is a trade-off against usability), direct calls to refreshAuthorization()/exchangeAuthorization() remain unguarded, and 2.x with skipIssuerMetadataValidation: true defeats issuer validation and should be disabled. If upgrading is not immediately possible, restrict OAuth clients to MCP servers you trust; note that 2.0.0 and 2.1.0 already accept expectedIssuer, so that pinning can be applied as an interim compensating control at the cost of manual configuration.

Affected VersionsENISA

typescript-sdk 2.0.0, < 2.2.0
typescript-sdk 1.12.0, < 1.31.0

Affected Packages

npm @modelcontextprotocol/client fix: 2.2.0
npm @modelcontextprotocol/sdk fix: 1.31.0
euvd typescript_sdk_1_12_0 fix: 1.31.0
euvd typescript_sdk_2_0_0 fix: 2.2.0

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 4 packages in npm, euvd

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The Model Context Protocol (MCP) TypeScript SDK implements an OAuth 2.x client used by HTTP-based MCP transports, the withOAuth() middleware, and direct auth()/fetchToken() calls; the client discovers the authorization server's metadata from the MCP server it is connecting to. The root cause is CWE-345, Insufficient Verification of Data Authenticity: the OAuth client accepted the authorization server identity selected by the peer (the MCP server) instead of pinning credentials to the issuer they were registered with, so cached tokens and client information were transmitted to whatever authorization-server URL the MCP server advertised. The fix introduces an issuer stamp on saved credentials and an expectedIssuer constructor option on bundled providers (ClientCredentialsProvider, PrivateKeyJwtProvider, StaticPrivateKeyJwtProvider, CrossAppAccessProvider); fetchToken() now throws AuthorizationServerMismatchError before transmitting anything when client information is bound to a different authorization server, OAuthTokensSchema and OAuthClientInformationSchema accept and preserve the optional issuer field, and constructing the bundled providers without expectedIssuer is deprecated with a console.warn. Note that the supplied tag set labels this 'Denial Of Service', which contradicts both the CWE-345 classification and the CVSS vector (C:H/I:N/A:N, confidentiality-only) - the authoritative assessment is pure credential disclosure, not availability loss. MCP servers built with the SDK and stdio clients are explicitly not affected, and CPE entries pkg:npm/@modelcontextprotocol_sdk and pkg:npm/@modelcontextprotocol_client confirm the two npm packages tracked.

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

Vendor (https://github.com/modelcontextprotocol/typescript-sdk) PRIMARY 7.5 HIGH
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
vuln.today AI 7.5 HIGH

Credential disclosure over HTTP with no interaction once a client connects, so C:H and AV:N/AC:L/PR:N/UI:N; no direct integrity or availability impact, so I:N/A:N.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
Red Hat 7.5 HIGH

Primary rating from Vendor (https://github.com/modelcontextprotocol/typescript-sdk).

CVSS VectorVendor: https://github.com/modelcontextprotocol/typescript-sdk

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
None
Availability
None

DescriptionCVE.org

Summary

In affected versions, the SDK's OAuth client let the MCP server decide which authorization server received the client's OAuth credentials. Credentials were not tied to the authorization server they belong to.

A malicious or compromised MCP server could name its own authorization server. With no user interaction, the client would send it:

  • the refresh_token and client_secret stored from an earlier sign-in
  • the client_secret or signed assertion configured on a bundled provider

Am I affected?

Yes, if both of these hold:

  • your application uses the SDK's OAuth client over HTTP, through any of:
  • an authProvider on a transport
  • the withOAuth() middleware
  • direct calls to auth() or fetchToken()
  • it may connect to an MCP server you do not fully trust while holding credentials for a legitimate authorization server

Affected versions:

  • @modelcontextprotocol/sdk 1.12.0 through 1.30.1
  • @modelcontextprotocol/client 2.0.0 through 2.1.0, only for:
  • bundled providers without expectedIssuer
  • credentials stored or supplied without issuer
  • direct calls to fetchToken()
  • providers that read storage back through OAuthTokensSchema or OAuthClientInformationSchema

Not affected:

  • MCP servers built with the SDK
  • stdio clients

Fix

Upgrade to:

  • 1.x: @modelcontextprotocol/sdk 1.31.0 or later
  • 2.x: @modelcontextprotocol/client 2.2.0 or later, and @modelcontextprotocol/core 2.2.0 or later if you import it directly

The client now records the authorization server as issuer on saved credentials and does not send them to a different one. The user signs in again, or the call throws.

In the following cases, upgrading to the patched version is not enough. You also need to make a change:

  • Bundled providers (ClientCredentialsProvider, PrivateKeyJwtProvider, StaticPrivateKeyJwtProvider, CrossAppAccessProvider): pass expectedIssuer, for example expectedIssuer: 'https://auth.example.com'. Without it they still use whichever authorization server the MCP server names.
  • Credentials saved without issuer: tokens and client information your OAuthClientProvider persisted (file, keychain, database) before upgrading, including everything 1.x saved before 1.31.0. They still go to whichever authorization server is named at first use. Add issuer to them, or clear them so users sign in again.
  • Your own OAuthClientProvider: save exactly what saveTokens() and saveClientInformation() are given, including issuer. For pre-registered credentials, include issuer in what clientInformation() returns.

Not covered by this fix:

  • a new interactive sign-in, which still goes to the authorization server the MCP server names. Only complete sign-ins for servers you trust.
  • refreshAuthorization() and exchangeAuthorization() called directly
  • 2.x with skipIssuerMetadataValidation: true

If an affected client may have connected to an untrusted MCP server, rotate its client secret or signing key and revoke its tokens.

If you cannot upgrade yet, connect OAuth clients only to MCP servers you trust. 2.0.0 and 2.1.0 already accept expectedIssuer.

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 1,133 npm packages depend on @modelcontextprotocol/client (721 direct, 418 indirect)
  • 98 npm packages depend on @modelcontextprotocol/sdk (84 direct, 15 indirect)

Ecosystem-wide dependent count for version 2.0.0 and other introduced versions.

Technical POC Analysis

No runnable PoC is present in the supplied evidence.

Full technical POC analysis - root cause, step-by-step exploitation and patch breakdown - is part of the Pro and Business plans.

Executive ViewAI

Why It Matters

A high-severity credential disclosure flaw in the widely used MCP TypeScript SDK (@modelcontextprotocol/sdk versions 1.12.0 through 1.30.1, plus @modelcontextprotocol/client 2.0.0 through 2.1.0) allows an attacker who controls or compromises an MCP server to silently harvest the OAuth refresh tokens and client secrets that any connecting application has stored. Because the leak occurs without user interaction and without authentication, any team shipping or operating MCP-enabled clients - including internal AI tooling and customer-facing integrations - could expose long-lived third-party credentials. Leadership should care because stolen refresh tokens and provider client secrets permit persistent, hard-to-detect access to downstream SaaS and identity providers, turning a single SDK dependency into an enterprise-wide trust and compliance exposure.

Business Impact: High
Compensating Controls

Apply vendor patch.

Threat Intelligence Overview

EPSS Score
0.2%
Top 94% exploitable
Prevalence
Medium
popular MCP SDK, but OAuth-client-over-HTTP-to-untrusted-server usage is a narrower subset
Threat Intel
1
1 sources
Data Quality
5 sources
Confidence: Medium
EUVD NVD CVE.org EPSS Vulnrichment GHSA Vendor GitHub

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.

SignalValue
Severity HIGH
CISA KEV No
Public POC No
EPSS 0.2%
Patch available Yes
Active threat No
Deciding rule
HIGH severity (CVSS 7.0-8.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision
Scheduled
Exploitation
None
System Exposure· derived
Open
Automatable
Yes
Human Impact
High
Technical Impact
Partial

Priority Score

38
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +38
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Vendor StatusVendor

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy