CVE-2026-104850
MCP TypeScript SDK: OAuth client could send credentials to an authorization server chosen by the MCP server
MCP TypeScript SDK is the official TypeScript SDK for Model Context Protocol servers and clients. Starting in version 1.12.0 and prior to versions 1.31.0 and 2.2.0, the SDK's OAuth client support let the MCP server a client connected to decide which authorization server received the client's OAuth credentials. Stored and pre-provisioned credentials were not bound to the authorization server they belong to. A malicious or compromised MCP server could name its own authorization server in its protected resource metadata. Without any user interaction, the client would send that server the refresh_token and client_secret stored from an earlier sign-in (1.x), or the configured client_secret or signed assertion of a bundled non-interactive provider (1.x and 2.x). Only those applications that use the SDK as an MCP client over HTTP with an authProvider: your own OAuthClientProvider, or the bundled ClientCredentialsProvider, PrivateKeyJwtProvider, StaticPrivateKeyJwtProvider or (2.x) CrossAppAccessProvider and that may connect to an MCP server the owners does not fully trust while holding credentials for a legitimate authorization server are affected. @modelcontextprotocol/sdk 1.31.0 (1.x) and @modelcontextprotocol/client 2.2.0 (2.x) patch the issue. A workaround for those who cannot upgrade is available. 2.0.0 and 2.1.0 already accept expectedIssuer. On 1.x, the only workaround is to connect OAuth-enabled clients only to MCP servers you trust.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.5
MCP TypeScript SDK: OAuth client could send credentials to an authorization server chosen by the MCP server
MCP TypeScript SDK is the official TypeScript SDK for Model Context Protocol servers and clients. Starting in version 1.12.0 and prior to versions 1.31.0 and 2.2.0, the SDK's OAuth client support let the MCP server a client connected to decide which authorization server received the client's OAuth credentials. Stored and pre-provisioned credentials were not bound to the authorization server they belong to. A malicious or compromised MCP server could name its own authorization server in its protected resource metadata. Without any user interaction, the client would send that server the refresh_token and client_secret stored from an earlier sign-in (1.x), or the configured client_secret or signed assertion of a bundled non-interactive provider (1.x and 2.x). Only those applications that use the SDK as an MCP client over HTTP with an authProvider: your own OAuthClientProvider, or the bundled ClientCredentialsProvider, PrivateKeyJwtProvider, StaticPrivateKeyJwtProvider or (2.x) CrossAppAccessProvider and that may connect to an MCP server the owners does not fully trust while holding credentials for a legitimate authorization server are affected. @modelcontextprotocol/sdk 1.31.0 (1.x) and @modelcontextprotocol/client 2.2.0 (2.x) patch the issue. A workaround for those who cannot upgrade is available. 2.0.0 and 2.1.0 already accept expectedIssuer. On 1.x, the only workaround is to connect OAuth-enabled clients only to MCP servers you trust.
- Record
CVE-2026-104850- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-345, CWE-522
- Updated
- 2026-11-02
EUVDEUVD-2026-93491
7.5
MCP TypeScript SDK is the official TypeScript SDK for Model Context Protocol servers and clients. Starting in version 1.12.0 and prior to versions 1.31.0 and 2.2.0, the SDK's OAuth client support let the MCP server a client connected to decide which authorization server received the client's OAuth credentials. Stored and pre-provisioned credentials were not bound to the authorization server they belong to. A malicious or compromised MCP server could name its own authorization server in its protected resource metadata. Without any user interaction, the client would send that server the refresh_token and client_secret stored from an earlier sign-in (1.x), or the configured client_secret or signed assertion of a bundled non-interactive provider (1.x and 2.x). Only those applications that use the SDK as an MCP client over HTTP with an authProvider: your own OAuthClientProvider, or the bundled ClientCredentialsProvider, PrivateKeyJwtProvider, StaticPrivateKeyJwtProvider or (2.x) CrossAppAccessProvider and that may connect to an MCP server the owners does not fully trust while holding credentials for a legitimate authorization server are affected. @modelcontextprotocol/sdk 1.31.0 (1.x) and @modelcontextprotocol/client 2.2.0 (2.x) patch the issue. A workaround for those who cannot upgrade is available. 2.0.0 and 2.1.0 already accept expectedIssuer. On 1.x, the only workaround is to connect OAuth-enabled clients only to MCP servers you trust.
- Record
EUVD-2026-93491- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-6qxp-vccf-f47h
7.5
MCP TypeScript SDK: OAuth client could send credentials to an authorization server chosen by the MCP server
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_tokenandclient_secretstored from an earlier sign-in - the
client_secretor 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
authProvideron a transport - the
withOAuth()middleware - direct calls to
auth()orfetchToken()
- an
- it may connect to an MCP server you do not fully trust while holding credentials for a legitimate authorization server
Affected versions:
@modelcontextprotocol/sdk1.12.0 through 1.30.1@modelcontextprotocol/client2.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
OAuthTokensSchemaorOAuthClientInformationSchema
- bundled providers without
Not affected:
- MCP servers built with the SDK
- stdio clients
Fix
Upgrade to:
- 1.x:
@modelcontextprotocol/sdk1.31.0 or later - 2.x:
@modelcontextprotocol/client2.2.0 or later, and@modelcontextprotocol/core2.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): passexpectedIssuer, for exampleexpectedIssuer: 'https://auth.example.com'. Without it they still use whichever authorization server the MCP server names. - Credentials saved without
issuer: tokens and client information yourOAuthClientProviderpersisted (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. Addissuerto them, or clear them so users sign in again. - Your own
OAuthClientProvider: save exactly whatsaveTokens()andsaveClientInformation()are given, includingissuer. For pre-registered credentials, includeissuerin whatclientInformation()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()andexchangeAuthorization()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.
- Record
GHSA-6qxp-vccf-f47h- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-345, CWE-522
- Updated
- 2026-11-02
NVD
7.5
MCP TypeScript SDK is the official TypeScript SDK for Model Context Protocol servers and clients. Starting in version 1.12.0 and prior to versions 1.31.0 and 2.2.0, the SDK's OAuth client support let the MCP server a client connected to decide which authorization server received the client's OAuth credentials. Stored and pre-provisioned credentials were not bound to the authorization server they belong to. A malicious or compromised MCP server could name its own authorization server in its protected resource metadata. Without any user interaction, the client would send that server the refresh_token and client_secret stored from an earlier sign-in (1.x), or the configured client_secret or signed assertion of a bundled non-interactive provider (1.x and 2.x). Only those applications that use the SDK as an MCP client over HTTP with an authProvider: your own OAuthClientProvider, or the bundled ClientCredentialsProvider, PrivateKeyJwtProvider, StaticPrivateKeyJwtProvider or (2.x) CrossAppAccessProvider and that may connect to an MCP server the owners does not fully trust while holding credentials for a legitimate authorization server are affected. @modelcontextprotocol/sdk 1.31.0 (1.x) and @modelcontextprotocol/client 2.2.0 (2.x) patch the issue. A workaround for those who cannot upgrade is available. 2.0.0 and 2.1.0 already accept expectedIssuer. On 1.x, the only workaround is to connect OAuth-enabled clients only to MCP servers you trust.
- Record
CVE-2026-104850- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-345, CWE-522
- Updated
- 2026-11-02
OSV
7.5
MCP TypeScript SDK: OAuth client could send credentials to an authorization server chosen by the MCP server
MCP TypeScript SDK is the official TypeScript SDK for Model Context Protocol servers and clients. Starting in version 1.12.0 and prior to versions 1.31.0 and 2.2.0, the SDK's OAuth client support let the MCP server a client connected to decide which authorization server received the client's OAuth credentials. Stored and pre-provisioned credentials were not bound to the authorization server they belong to. A malicious or compromised MCP server could name its own authorization server in its protected resource metadata. Without any user interaction, the client would send that server the refresh_token and client_secret stored from an earlier sign-in (1.x), or the configured client_secret or signed assertion of a bundled non-interactive provider (1.x and 2.x). Only those applications that use the SDK as an MCP client over HTTP with an authProvider: your own OAuthClientProvider, or the bundled ClientCredentialsProvider, PrivateKeyJwtProvider, StaticPrivateKeyJwtProvider or (2.x) CrossAppAccessProvider and that may connect to an MCP server the owners does not fully trust while holding credentials for a legitimate authorization server are affected. @modelcontextprotocol/sdk 1.31.0 (1.x) and @modelcontextprotocol/client 2.2.0 (2.x) patch the issue. A workaround for those who cannot upgrade is available. 2.0.0 and 2.1.0 already accept expectedIssuer. On 1.x, the only workaround is to connect OAuth-enabled clients only to MCP servers you trust.
- Record
CVE-2026-104850- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-345, CWE-522
- Updated
- 2026-11-02
OSVGHSA-6qxp-vccf-f47h
7.5
MCP TypeScript SDK: OAuth client could send credentials to an authorization server chosen by the MCP server
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_tokenandclient_secretstored from an earlier sign-in - the
client_secretor 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
authProvideron a transport - the
withOAuth()middleware - direct calls to
auth()orfetchToken()
- an
- it may connect to an MCP server you do not fully trust while holding credentials for a legitimate authorization server
Affected versions:
@modelcontextprotocol/sdk1.12.0 through 1.30.1@modelcontextprotocol/client2.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
OAuthTokensSchemaorOAuthClientInformationSchema
- bundled providers without
Not affected:
- MCP servers built with the SDK
- stdio clients
Fix
Upgrade to:
- 1.x:
@modelcontextprotocol/sdk1.31.0 or later - 2.x:
@modelcontextprotocol/client2.2.0 or later, and@modelcontextprotocol/core2.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): passexpectedIssuer, for exampleexpectedIssuer: 'https://auth.example.com'. Without it they still use whichever authorization server the MCP server names. - Credentials saved without
issuer: tokens and client information yourOAuthClientProviderpersisted (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. Addissuerto them, or clear them so users sign in again. - Your own
OAuthClientProvider: save exactly whatsaveTokens()andsaveClientInformation()are given, includingissuer. For pre-registered credentials, includeissuerin whatclientInformation()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()andexchangeAuthorization()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.
- Record
GHSA-6qxp-vccf-f47h- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-345, CWE-522
- Updated
- 2026-11-02
Show 10 moreShow less
OSVCLSA-2026-1791626582 No score
TuxCare security update for @modelcontextprotocol/sdk (1 CVE)
TuxCare rebuilt @modelcontextprotocol/sdk to address 1 CVE. Fixed in 1.30.1-tuxcare.1.
- Record
CLSA-2026-1791626582- Updated
- 2026-11-02
OSVCLSA-2026-1791679180 No score
TuxCare security update for @modelcontextprotocol/sdk (1 CVE)
TuxCare rebuilt @modelcontextprotocol/sdk to address 1 CVE. Fixed in 1.30.0-tuxcare.1.
- Record
CLSA-2026-1791679180- Updated
- 2026-11-02
OSVCLSA-2026-1791835900 No score
TuxCare security update for @modelcontextprotocol/sdk (1 CVE)
TuxCare rebuilt @modelcontextprotocol/sdk to address 1 CVE. Fixed in 1.29.0-tuxcare.1.
- Record
CLSA-2026-1791835900- Updated
- 2026-11-02
OSVCLSA-2026-1791839313 No score
TuxCare security update for @modelcontextprotocol/sdk (1 CVE)
TuxCare rebuilt @modelcontextprotocol/sdk to address 1 CVE. Fixed in 1.26.0-tuxcare.1.
- Record
CLSA-2026-1791839313- Updated
- 2026-11-02
OSVCLSA-2026-1792257408 No score
TuxCare security update for @modelcontextprotocol/sdk (1 CVE)
TuxCare rebuilt @modelcontextprotocol/sdk to address 1 CVE. Fixed in 1.17.3-tuxcare.3.
- Record
CLSA-2026-1792257408- Updated
- 2026-11-02
OSVCLSA-2026-1792262854 No score
TuxCare security update for @modelcontextprotocol/sdk (1 CVE)
TuxCare rebuilt @modelcontextprotocol/sdk to address 1 CVE. Fixed in 1.24.0-tuxcare.3.
- Record
CLSA-2026-1792262854- Updated
- 2026-11-02
OSVCLSA-2026-1792263903 No score
TuxCare security update for @modelcontextprotocol/sdk (1 CVE)
TuxCare rebuilt @modelcontextprotocol/sdk to address 1 CVE. Fixed in 1.25.2-tuxcare.3.
- Record
CLSA-2026-1792263903- Updated
- 2026-11-02
OSVCLSA-2026-1793112371 No score
TuxCare security update for @modelcontextprotocol/sdk (6 CVEs)
TuxCare rebuilt @modelcontextprotocol/sdk to address 6 CVEs. Fixed in 1.13.3-tuxcare.2.
- Record
CLSA-2026-1793112371- Updated
- 2026-11-02
OSVCLSA-2026-1793207764 No score
TuxCare security update for @modelcontextprotocol/client (1 CVE)
TuxCare rebuilt @modelcontextprotocol/client to address 1 CVE. Fixed in 2.0.0-tuxcare.1.
- Record
CLSA-2026-1793207764- Updated
- 2026-11-02
OSVROOT-APP-NPM-CVE-2026-104850 No score
CVE-2026-104850 in @modelcontextprotocol/sdk - Patched by Root
Root has patched CVE-2026-104850 in the @modelcontextprotocol/sdk package for Root:npm. Multiple fixed versions available.
- Record
ROOT-APP-NPM-CVE-2026-104850- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
@modelcontextprotocol/sdknpm |
1.12.0 up to 1.31.0 | 1.31.0 |
@modelcontextprotocol/clientnpm |
2.0.0 up to 2.2.0 | 2.2.0 |
@modelcontextprotocol/sdkTuxCare:npm |
1.30.1-tuxcare.0 up to 1.30.1-tuxcare.1, plus listed versions 1.30.1 |
1.30.1-tuxcare.1 |
@modelcontextprotocol/sdkTuxCare:npm |
1.30.0-tuxcare.0 up to 1.30.0-tuxcare.1, plus listed versions 1.30.0 |
1.30.0-tuxcare.1 |
@modelcontextprotocol/sdkTuxCare:npm |
1.29.0-tuxcare.0 up to 1.29.0-tuxcare.1, plus listed versions 1.29.0 |
1.29.0-tuxcare.1 |
@modelcontextprotocol/sdkTuxCare:npm |
1.26.0-tuxcare.0 up to 1.26.0-tuxcare.1, plus listed versions 1.26.0 |
1.26.0-tuxcare.1 |
@modelcontextprotocol/sdkTuxCare:npm |
1.17.3-tuxcare.0 up to 1.17.3-tuxcare.3, plus listed versions 1.17.31.17.3-tuxcare.11.17.3-tuxcare.2 |
1.17.3-tuxcare.3 |
@modelcontextprotocol/sdkTuxCare:npm |
1.24.0-tuxcare.0 up to 1.24.0-tuxcare.3, plus listed versions 1.24.01.24.0-tuxcare.11.24.0-tuxcare.2 |
1.24.0-tuxcare.3 |
@modelcontextprotocol/sdkTuxCare:npm |
1.25.2-tuxcare.0 up to 1.25.2-tuxcare.3, plus listed versions 1.25.21.25.2-tuxcare.11.25.2-tuxcare.2 |
1.25.2-tuxcare.3 |
@modelcontextprotocol/sdkTuxCare:npm From an advisory covering 6 CVEs |
1.13.3-tuxcare.0 up to 1.13.3-tuxcare.2, plus listed versions 1.13.31.13.3-tuxcare.1 |
1.13.3-tuxcare.2 |
@modelcontextprotocol/clientTuxCare:npm |
2.0.0-tuxcare.0 up to 2.0.0-tuxcare.1, plus listed versions 2.0.0 |
2.0.0-tuxcare.1 |
@modelcontextprotocol/sdkRoot:npm |
before 1.26.0-aikido.1 | 1.26.0-aikido.11.30.0-aikido.11.29.0-aikido.11.30.0-aikido.21.26.0-aikido.21.29.0-aikido.21.26.0-aikido.31.26.0-aikido.41.31.0-aikido.1 |
@rootio/modelcontextprotocol__sdkRoot:npm |
before 1.26.0-root.io.1 | 1.26.0-root.io.11.30.0-root.io.11.29.0-root.io.11.30.0-root.io.21.26.0-root.io.21.29.0-root.io.21.26.0-root.io.31.26.0-root.io.41.31.0-root.io.1 |
Public exploits
Links only. Every CVE stores no exploit code.
| Source | Link | Date |
|---|---|---|
| PoC in GitHub | Iceman2050/mcp-oauth-discovery-prober | 2026-10-17 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV, PoC in GitHub |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-104850 is a high vulnerability (CVSS 7.5) in Modelcontextprotocol Typescript-sdk, published October 6, 2026. Public exploit code exists. EPSS puts the chance of exploitation in the next 30 days at 0.28%, the 20th percentile. Fixed in @modelcontextprotocol/sdk 1.31.0.
References
github.com/modelcontextprotocol/typescript-sdk/security/advisories/GHSA-6qxp-vccf-f47h
github.com/modelcontextprotocol/typescript-sdk/pull/2887
github.com/modelcontextprotocol/typescript-sdk/commit/edd12e282620ebf770d67316f19cf91d4112a1bd
github.com/modelcontextprotocol/typescript-sdk/releases/tag/v2.2.0
github.com/advisories/GHSA-6qxp-vccf-f47h
github.com/CVEProject/cvelistV5/tree/main/cves/2026/104xxx/CVE-2026-104850.json
nvd.nist.gov/vuln/detail/CVE-2026-104850
github.com/modelcontextprotocol/typescript-sdk