Skip to main content

MCP TypeScript SDK CVE-2026-111771

MEDIUM
Incorrect Authorization (CWE-863)
2026-10-20 https://github.com/modelcontextprotocol/typescript-sdk GHSA-rvq5-wwqv-78pq
6.8
CVSS 3.1 · GitHub Advisory
View

Attack ChainAIDerived

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

  1. Access
    Obtain valid token for another service
  2. Delivery
    Identify MCP server sharing authz server
  3. Exploit
    Replay token to requireBearerAuth endpoint
  4. Execution
    Audience check absent, token accepted
  5. Impact
    Access unauthorized MCP tools and data

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V8 - Authorization Authorization logic validation
MITRE ATT&CK

1 technique across 1 tactic: Privilege Escalation

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

Exploitation requires a specific, documented combination: (1) the MCP HTTP server uses requireBearerAuth() or verifyBearerToken() from an affected SDK version (@modelcontextprotocol/sdk 1.6.0-1.31.0, @modelcontextprotocol/server 2.0.0-2.2.0, @modelcontextprotocol/express 2.0.0-2.0.1, or @modelcontextprotocol/server-legacy 2.0.0-2.3.0); (2) the same authorization server issues valid tokens for OTHER services besides this MCP server; and (3) the application's own verifyAccessToken() does not independently validate the token's 'aud' (audience) claim. Limiting factors that reduce real-world exposure: the attacker must already hold a valid token issued by that shared authorization server for a different service (PR:L), so this is not an unauthenticated bypass; environments using a dedicated single-audience authorization server, or whose verifyAccessToken() already checks 'aud', are not exploitable. Critically, the patched versions ship the 'expectedResource' audience check OFF by default - remediation requires both setting expectedResource on requireBearerAuth() and returning the token audience as AuthInfo.resource from verifyAccessToken(); upgrading alone changes nothing.

Impact

This is a moderate-severity authorization flaw (CWE-863, missing token audience validation) rated CVSS 6.8 with vector AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N. The signals are internally consistent and point to a real-but-conditional risk rather than a drop-everything emergency. The network vector (AV:N) and high confidentiality/integrity impact (C:H/I:H) are offset by two dampening metrics: AC:H reflects that exploitation depends on a specific deployment topology (one authorization server issuing tokens for multiple services AND the application not checking 'aud' itself), and PR:L reflects that the attacker must already possess a valid token legitimately issued for some other service by that shared authorization server - this is a confused-deputy/token-reuse condition, not an anonymous bypass. No EPSS score, no CISA KEV listing, and no public exploit were provided in the intelligence, so the exploitation status is 'no public exploit identified at time of analysis'; there is no evidence of active exploitation. The real priority is driven by the sensitivity of the data behind affected MCP servers and by how common the multi-service shared-authorization-server pattern is in a given environment, not by raw score. Note one nuance to verify: the patch is off by default (opt-in via 'expectedResource'), so merely upgrading does NOT remediate - this materially affects real-world residual risk and should be weighted in prioritization.

Exploit ScenarioDerived

An organization runs several services (e.g., an MCP server and an unrelated API) that all accept bearer tokens from one shared OAuth authorization server, and the MCP server's verifyAccessToken() does not check the token's audience. An attacker who legitimately obtains a token scoped for the other, lower-value service replays that same token against the MCP server, which accepts it and grants access to MCP tools and data it was never authorized for. No public exploit code was identified; the attack is a straightforward token replay requiring no special tooling once a valid cross-service token is held.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available

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

Alert me

AnalysisAIv1 – Oct 20, 2026

Bearer-token authorization bypass in the Model Context Protocol TypeScript SDK packages lets a token minted for a different service be accepted by an MCP HTTP server built on requireBearerAuth() or verifyBearerToken(), giving the token holder the identity, scopes and tool access of an authenticated MCP client. Affected are @modelcontextprotocol/sdk 1.6.0-1.31.0, @modelcontextprotocol/server 2.0.0-2.2.0, @modelcontextprotocol/express 2.0.0-2.0.1 and @modelcontextprotocol/server-legacy 2.0.0-2.3.0, but only deployments whose authorization server also issues tokens for other services and whose verifyAccessToken() does not itself check the 'aud' claim. The flaw is authenticated (CVSS 6.8, AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N) since the attacker must already hold a valid token from that shared authorization server; no public exploit code or confirmed active exploitation was identified at time of analysis, and note that upgrading alone does not remediate - the new expectedResource audience check ships disabled by default.

RemediationAI

Vendor-released patch: @modelcontextprotocol/sdk 1.32.0, @modelcontextprotocol/server 2.3.0, @modelcontextprotocol/express 2.0.2 and @modelcontextprotocol/server-legacy 2.3.1, with the upstream fix visible in commits 40f8f4e229d963cd7fd2890bda2aeebe7005299a, 5a0724d14cf34a27a3b070224d2996cdd611df9f and 5a1867390b91b8836f49af76c45427279f513325 and documented at https://github.com/modelcontextprotocol/typescript-sdk/security/advisories/GHSA-rvq5-wwqv-78pq. Upgrading is necessary but not sufficient: the new expectedResource option is off by default, so you must also pass the audience your authorization server stamps into tokens for this server - requireBearerAuth({ verifier, expectedResource: new URL('https://mcp.example.com/mcp') }) - and return that audience from verifyAccessToken() as AuthInfo.resource, itself a URL, sourced from the JWT 'aud' claim or the introspection 'aud' field; applying only the first change causes every request to return 401, so make both changes together and verify with a token issued for another service, which should now receive 401 invalid_token. Express users must additionally upgrade @modelcontextprotocol/express to 2.0.2, since 2.0.1 silently drops expectedResource and its options type rejects it at compile time. If you cannot upgrade yet, implement the equivalent control in application code by rejecting inside verifyAccessToken() any token whose 'aud' does not include your server's URL - this closes the issue on every affected version with no dependency change; the trade-off is that the check lives in your verifier rather than the middleware, so it must be duplicated in each MCP server and kept in sync with the resource identifiers your authorization server actually issues. Environments where the authorization server is dedicated to a single audience, or where 'aud' is already validated, can treat this as informational but should still plan the upgrade to avoid future regressions.

Affected Packages

npm @modelcontextprotocol/express fix: 2.0.2
npm @modelcontextprotocol/sdk fix: 1.32.0
npm @modelcontextprotocol/server fix: 2.3.0
npm @modelcontextprotocol/server-legacy fix: 2.3.1

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 4 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 SDK implements OAuth 2.0 bearer-token protection (RFC 6750) for streamable HTTP servers, delegating token validation to an application-supplied OAuthTokenVerifier whose verifyAccessToken() returns AuthInfo. Because AuthInfo carried no field for the token's intended audience and requireBearerAuth()/verifyBearerToken() had no expectedResource concept, the middleware could only check token validity, expiry and scopes - never the JWT 'aud' claim or the introspection response's 'aud' field that binds a token to a specific resource server (the RFC 8707 resource-indicator model). This is CWE-863 (Incorrect Authorization): a classic cross-service or 'confused deputy' audience-confusion pattern where a multi-tenant authorization server issuing tokens for several relying parties is trusted implicitly by every one of them. The upstream commits add an optional expectedResource option on a new VerifyBearerTokenOptions type (extending the unchanged BearerAuthOptions), compared as a string against AuthInfo.resource while ignoring a fragment and one trailing slash, and enforced through the Express requireBearerAuth() pass-through in @modelcontextprotocol/express 2.0.2 - 2.0.1 does not forward the option, so Express deployments must upgrade that package too. The corresponding CPE entries are the four npm packages pkg:npm/@modelcontextprotocol_sdk, _server, _express and _server-legacy.

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

GitHub Advisory PRIMARY 6.8 MEDIUM
AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N
vuln.today AI 6.8 MEDIUM

AV:N (network bearer auth); AC:H because it needs a shared multi-service authz server and no app-side aud check; PR:L because the attacker needs a valid token for another service; C:H/I:H for unauthorized MCP access, A:N.

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

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

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

DescriptionGitHub Advisory

Summary

In affected versions, the SDK's server-side bearer authentication had no way to check that a token was issued for your server (its audience). Where one authorization server issues tokens for several services, a valid token for another service was also accepted by your MCP server.

Am I affected?

Yes, if your HTTP server uses requireBearerAuth() or verifyBearerToken(), its authorization server also issues tokens for other services, and your verifyAccessToken() does not check the token's audience (aud) itself.

Affected versions:

  • @modelcontextprotocol/sdk 1.6.0 through 1.31.0
  • @modelcontextprotocol/server 2.0.0 through 2.2.0
  • @modelcontextprotocol/express 2.0.0 through 2.0.1
  • @modelcontextprotocol/server-legacy 2.0.0 through 2.3.0

Fix

Upgrade to:

  • 1.x: @modelcontextprotocol/sdk 1.32.0 or later
  • 2.x: @modelcontextprotocol/server 2.3.0 or later, together with @modelcontextprotocol/express 2.0.2 or later if you use it
  • @modelcontextprotocol/server-legacy 2.3.1 or later

Upgrading alone changes nothing. The patched versions add an expectedResource setting that is off by default. To turn the check on, make both of these changes together:

  1. Pass the audience your authorization server puts in tokens for your server: requireBearerAuth({ verifier, expectedResource: new URL('https://mcp.example.com/mcp') }).
  2. Return the token's audience from verifyAccessToken() as AuthInfo.resource, also a URL.

A token for another service then gets 401. With only the first change, every request gets 401.

If you cannot upgrade yet, reject any token whose aud does not include your server inside verifyAccessToken(). That closes the issue on every version.

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 1,417 npm packages depend on @modelcontextprotocol/server (1,063 direct, 361 indirect)

Ecosystem-wide dependent count for version 2.0.0.

Threat Intelligence Overview

Prevalence
Medium
official MCP SDK, widely adopted in AI tooling but developer-facing and still emerging
Threat Intel
1
1 source
Data Quality
3 sources
Confidence: Low
NVD CVE.org GHSA 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 MEDIUM
CISA KEV No
Public POC No
EPSS N/A
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.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· derived
Scheduled
Exploitation· derived
None
System Exposure· derived
Open
Automatable· derived
No
Human Impact· derived
Medium

Priority Score

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

Attack Technique

Authentication bypass attacks exploit flaws in the verification mechanisms that control access to systems and applications.

Affected Products (CPE)GitHub Advisory

pkg:npm/@modelcontextprotocol_sdk
pkg:npm/@modelcontextprotocol_server
pkg:npm/@modelcontextprotocol_express
pkg:npm/@modelcontextprotocol_server-legacy

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