CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-116684

CVE-2026-116684: Resource-Confusion Authorization Bypass in Model Context Protocol Python SDK

Amit Schendel
Amit Schendel
Senior Security Researcher

Oct 28, 2026·9 min read·5 visits

Executive Summary (TL;DR)

The Model Context Protocol (MCP) Python SDK fails to validate the target audience or RFC 8707 resource indicator of incoming OAuth 2.0 bearer tokens in `BearerAuthBackend`. Attackers holding valid tokens issued by a shared Identity Provider for unrelated applications can replay those tokens against an MCP server to achieve unauthorized access and execute privileged tools. Upgrading to versions 1.30.0 or 2.2.0 and explicitly enabling `validate_token_resource=True` in `AuthSettings` is required to remediate the flaw.

CVE-2026-116684 is an incorrect authorization vulnerability (CWE-863) in the Model Context Protocol (MCP) Python SDK (`modelcontextprotocol/python-sdk`). The server-side bearer authentication middleware (`BearerAuthBackend`) verifies token cryptographic signatures and expiration timestamps via `TokenVerifier`, but fails to verify that the token's audience (`aud` claim or RFC 8707 resource indicator) matches the receiving MCP server's configured `resource_server_url`. In multi-service environments sharing a single OAuth 2.0 Authorization Server, an attacker possessing a valid token for an unrelated service can replay it against the MCP server to gain unauthorized access to protected tools, resources, and prompts.

Vulnerability Overview

The Model Context Protocol (MCP) Python SDK (mcp) provides the official server and client implementation for building integrations that expose data, tools, and prompt templates to Large Language Model (LLM) applications. When deployed over HTTP transports (such as Server-Sent Events or Streamable HTTP), MCP servers rely on OAuth 2.0 bearer token authentication to restrict access to sensitive capabilities. This authentication layer is managed by the BearerAuthBackend middleware located in src/mcp/server/auth/middleware/bearer_auth.py.

In versions >= 1.10.0, < 1.30.0 and >= 2.0.0, < 2.2.0, BearerAuthBackend suffers from an incorrect authorization vulnerability classified under CWE-863 (Incorrect Authorization). When an MCP server is configured with AuthSettings and a custom or standard TokenVerifier, the middleware validates that the incoming bearer token is cryptographically authentic and un-expired, but fails to verify whether the token was actually issued for the receiving MCP server.

In enterprise architectures, a single OAuth 2.0 Authorization Server or Identity Provider (IdP) routinely issues access tokens for multiple distinct resource servers (APIs, microservices, and MCP servers). Under RFC 7519 (JWT) and RFC 8707 (Resource Indicators for OAuth 2.0), tokens are bound to their intended recipient via the aud (Audience) claim or the resource indicator. Because the MCP SDK omitted checks comparing AccessToken.resource against the server's configured resource_server_url, any valid token issued by the trusted IdP for an unrelated service is accepted by the MCP server, allowing cross-service token replay and unauthorized privilege escalation.

Root Cause Analysis

The root cause of CVE-2026-116684 lies in an incomplete authentication state check within BearerAuthBackend.authenticate() and a disconnection between AuthSettings.resource_server_url and the authentication middleware initialization. When a developer configures an MCP server, they supply an AuthSettings object containing issuer_url (the OAuth 2.0 Authorization Server) and resource_server_url (the canonical URL of the MCP server itself).

During request processing, BearerAuthBackend.authenticate() extracts the token from the Authorization: Bearer <token> HTTP header and passes the raw token string to self.token_verifier.verify_token(token). The TokenVerifier returns an AccessToken Pydantic model (defined in mcp.server.auth.provider), which contains token, client_id, scopes, expires_at, and an optional resource attribute representing the RFC 8707 resource indicator or audience.

Prior to the patch, BearerAuthBackend was instantiated solely with self._token_verifier and had no reference to self.settings.auth.resource_server_url. After calling verify_token(), the middleware checked only two conditions: whether the returned auth_info object was None, and whether auth_info.expires_at was less than the current Unix timestamp. It completely ignored auth_info.resource.

Consequently, if the developer's TokenVerifier implementation only verified the cryptographic signature against the IdP's JSON Web Key Set (JWKS) and decoded the claims into AccessToken—expecting the framework to enforce server-level settings—any token bearing a valid signature from the IdP and matching scopes was granted full access to the MCP session.

Code Analysis

The vulnerability was resolved across the v2.x branch in commit 0c9136841ff092987a20700ff9c2c9789bda2f40 (PR #3447) and backported to the v1.x maintenance branch in commit 8c2fa6eabacde869d75568e33b9d75568e33b9d466b58c2f512 (PR #3451). The patch modifies three primary components: the authentication settings model, the server middleware wiring, and the bearer authentication backend.

First, src/mcp/server/auth/middleware/bearer_auth.py was updated to accept resource_server_url in its constructor and enforce URL-normalized comparison against auth_info.resource during request authentication:

class BearerAuthBackend(AuthenticationBackend):
    def __init__(self, token_verifier: TokenVerifier, *, resource_server_url: AnyHttpUrl | None = None):
        self.token_verifier = token_verifier
        # Store the target MCP server's canonical resource URL
        self.resource_server_url = resource_server_url
 
    async def authenticate(self, conn: HTTPConnection):
        auth_header = next(
            (val for key, val in conn.headers.raw if key.lower() == b"authorization"),
            None,
        )
        if not auth_header:
            return None
 
        parts = auth_header.decode("latin-1").split(" ", 1)
        if len(parts) != 2 or parts[0].lower() != "bearer":
            return None
 
        token = parts[1]
        auth_info = await self.token_verifier.verify_token(token)
        if auth_info is None:
            return None
 
        if auth_info.expires_at and auth_info.expires_at < int(time.time()):
            return None
 
        # PATCHED: Verify that the token's resource indicator matches this server
        if self.resource_server_url and not self._issued_for_this_resource(auth_info.resource):
            logger.warning(
                "Bearer token resource %r is not resource_server_url %s",
                auth_info.resource,
                self.resource_server_url,
            )
            return None
 
        return AuthCredentials(auth_info.scopes), AuthenticatedUser(auth_info)
 
    def _issued_for_this_resource(self, resource: str | None) -> bool:
        """Compare as URLs (so case and default-port spelling do not matter), a trailing slash aside."""
        try:
            token_resource = str(AnyHttpUrl(resource or ""))
        except ValidationError:
            return False
        return token_resource.removesuffix("/") == str(self.resource_server_url).removesuffix("/")

Second, src/mcp/server/auth/settings.py introduced the validate_token_resource boolean field on AuthSettings, along with a Pydantic @model_validator that checks configuration consistency and issues a MCPDeprecationWarning if resource_server_url is configured without an explicit validate_token_resource setting:

class AuthSettings(BaseModel):
    issuer_url: AnyHttpUrl
    resource_server_url: AnyHttpUrl | None = Field(default=None)
    validate_token_resource: bool | None = Field(default=None)
 
    @model_validator(mode="after")
    def _check_validate_token_resource(self) -> Self:
        if self.validate_token_resource and self.resource_server_url is None:
            raise ValueError("validate_token_resource requires resource_server_url")
        if self.validate_token_resource is None and self.resource_server_url is not None:
            warnings.warn(
                "`AuthSettings.validate_token_resource` is not set, so bearer tokens are not checked "
                "against `resource_server_url`; it will default to True in 3.0 when `resource_server_url` is "
                "set. Set it to True to have the server refuse tokens issued for another resource, or to "
                "False if your TokenVerifier validates the token's audience itself.",
                MCPDeprecationWarning,
                stacklevel=3,
            )
        return self

Third, in src/mcp/server/mcpserver/server.py (and lowlevel/server.py), the AuthenticationMiddleware initialization was updated to conditionally pass resource_server_url to BearerAuthBackend when self.settings.auth.validate_token_resource evaluates to True.

> [!WARNING] > Fix Completeness & Residual Risk: To preserve backwards compatibility in minor version releases (1.30.0 and 2.2.0), validate_token_resource defaults to None (which behaves as False). Merely upgrading the mcp package without modifying server initialization code leaves the deployment vulnerable to token replay until MCP SDK 3.0 makes True the default.

Exploitation

Exploiting CVE-2026-116684 requires a specific architectural prerequisite: the target MCP server must rely on an OAuth 2.0 Authorization Server / IdP that is shared with at least one other application or resource server, and the attacker must be able to obtain a valid access token for that secondary service.

Consider an enterprise environment where an internal Identity Provider (https://idp.corp.example.com) manages authentication for multiple internal services. Service A is a low-privilege employee profile service (https://profile.corp.example.com), and Service B is a privileged MCP server (https://mcp-admin.corp.example.com/mcp) that exposes database query and infrastructure management tools to AI agents. Both services validate tokens using the IdP's public JWKS endpoint.

  1. Token Acquisition: An authenticated low-privilege user (or an attacker who compromises the low-privilege profile service) initiates a standard OAuth 2.0 flow against https://idp.corp.example.com requesting an access token for resource=https://profile.corp.example.com. If the IdP permits generic scopes (or if the MCP server does not enforce unique custom scopes via required_scopes), the IdP returns a signed JWT containing:
{
  "iss": "https://idp.corp.example.com",
  "sub": "user-9481",
  "aud": "https://profile.corp.example.com",
  "client_id": "profile-web-app",
  "exp": 1793088000,
  "scope": "read write"
}
  1. Cross-Service Token Replay: The attacker sends an MCP JSON-RPC initialization or tool execution request directly to the target MCP server (https://mcp-admin.corp.example.com/mcp), supplying the token minted for the profile service in the HTTP Authorization header:
POST /mcp HTTP/1.1
Host: mcp-admin.corp.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
 
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "execute_sql_query",
    "arguments": {
      "query": "SELECT * FROM sensitive_credentials;"
    }
  }
}
  1. Authentication Bypass: The MCP server's TokenVerifier verifies the RSA signature against https://idp.corp.example.com/.well-known/jwks.json and populates AccessToken(resource="https://profile.corp.example.com", ...). Because BearerAuthBackend in vulnerable versions fails to compare AccessToken.resource against https://mcp-admin.corp.example.com/mcp, the middleware authenticates the request and executes the privileged execute_sql_query tool.

Impact Assessment

CVE-2026-116684 is scored at CVSS v3.1 6.8 (Medium) with the vector CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N. The Attack Complexity is rated High (AC:H) and Privileges Required is Low (PR:L) because successful exploitation depends on a multi-resource IdP deployment, the attacker possessing credentials to obtain a valid token for a sibling service, and the MCP server's custom TokenVerifier not already performing independent aud claim verification.

When these conditions are met, the Confidentiality (C:H) and Integrity (I:H) impacts are high. Model Context Protocol servers are specifically designed to act as bridges between LLM clients and sensitive backend infrastructure, frequently exposing tools capable of reading internal filesystems, querying production databases, interacting with source control, or invoking cloud provider APIs.

By bypassing resource-level authorization, an attacker who should only have access to a low-sensitivity application within the same identity domain can laterally move into the MCP server context. The attacker can enumerate all registered MCP resources (resources/list, resources/read), extract proprietary prompt templates (prompts/get), and invoke state-modifying tools (tools/call) with the full privileges of the MCP server process.

Remediation

Remediating CVE-2026-116684 requires a three-step process: upgrading the mcp Python package, explicitly opting into resource validation in AuthSettings, and ensuring the TokenVerifier implementation populates the AccessToken.resource field.

First, upgrade the mcp package to version 1.30.0 (for v1.x deployments) or 2.2.0 (for v2.x deployments). Second, configure validate_token_resource=True alongside resource_server_url in AuthSettings. Third, ensure that the TokenVerifier.verify_token() implementation extracts the aud claim or RFC 8707 resource indicator from the verified token and passes it to AccessToken(resource=...).

from pydantic import AnyHttpUrl
from mcp.server.mcpserver import MCPServer
from mcp.server.auth.settings import AuthSettings
from mcp.server.auth.provider import AccessToken, TokenVerifier
 
RESOURCE_URL = "https://mcp.example.com/mcp"
 
class HardenedJWTVerifier(TokenVerifier):
    def __init__(self, resource_url: str):
        self.resource_url = resource_url
 
    async def verify_token(self, token: str) -> AccessToken | None:
        claims = decode_and_verify_jwt_signature(token)
        if not claims:
            return None
 
        # Handle single string or list of strings in JWT 'aud' claim
        aud = claims.get("aud")
        audiences = aud if isinstance(aud, list) else [aud] if aud else []
        own = self.resource_url.rstrip("/")
        
        # Select matching audience or fallback to first entry so middleware rejects mismatches
        matching_resource = next(
            (a for a in audiences if a.rstrip("/") == own),
            audiences[0] if audiences else None,
        )
 
        return AccessToken(
            token=token,
            client_id=claims.get("client_id", "unknown"),
            scopes=claims.get("scope", "").split(),
            expires_at=claims.get("exp"),
            resource=matching_resource,  # CRITICAL: Populate resource for middleware check
        )
 
mcp = MCPServer(
    "ProductionMCPServer",
    token_verifier=HardenedJWTVerifier(resource_url=RESOURCE_URL),
    auth=AuthSettings(
        issuer_url=AnyHttpUrl("https://auth.example.com"),
        resource_server_url=AnyHttpUrl(RESOURCE_URL),
        required_scopes=["mcp:tools"],
        validate_token_resource=True,  # CRITICAL: Enforce audience validation in BearerAuthBackend
    ),
)

If an immediate upgrade to 1.30.0 or 2.2.0 is not feasible, developers can mitigate the vulnerability directly inside their custom TokenVerifier.verify_token() method. By passing audience=RESOURCE_URL directly into the underlying JWT decoding library (such as PyJWT's jwt.decode(..., audience=...) or Authlib) and returning None if the audience does not match the MCP server's canonical URL, unauthenticated cross-service tokens will be rejected before reaching BearerAuthBackend.

Official Patches

Model Context ProtocolGitHub Security Advisory GHSA-w4fh-qvv9-3v23
Model Context ProtocolMCP Python SDK v1.30.0 Release
Model Context ProtocolMCP Python SDK v2.2.0 Release

Fix Analysis (2)

Technical Appendix

CVSS Score
6.8/ 10
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N
EPSS Probability
0.05%
Top 100% most exploited

Affected Systems

Model Context Protocol Python SDK (mcp) >= 1.10.0, < 1.30.0Model Context Protocol Python SDK (mcp) >= 2.0.0, < 2.2.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
Model Context Protocol Python SDK (mcp)
modelcontextprotocol
>= 1.10.0, < 1.30.01.30.0
Model Context Protocol Python SDK (mcp)
modelcontextprotocol
>= 2.0.0, < 2.2.02.2.0
AttributeDetail
Vulnerability ClassCWE-863: Incorrect Authorization (OAuth 2.0 Audience / Resource Confusion)
Affected Componentmcp.server.auth.middleware.bearer_auth.BearerAuthBackend
Attack VectorNetwork (Cross-Service OAuth 2.0 Bearer Token Replay)
CVSS v3.1 Score6.8 Medium (CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:N)
ImpactUnauthorized access to MCP tools, resources, and prompts
Patched Versions1.30.0 (v1.x) and 2.2.0 (v2.x) with validate_token_resource=True
Exploit StatusNo known public exploits in the wild
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
T1550.001Use Alternate Authentication Material: Application Access Token
Defense Evasion / Lateral Movement
CWE-863
Incorrect Authorization

The software performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly verify that the actor is authorized to access the specific resource requested.

Vulnerability Timeline

Fix commit 0c9136841ff092987a20700ff9c2c9789bda2f40 merged into main branch via PR #3447
2026-09-05
Backport fix commit 8c2fa6eabacde869d75568e33b9d466b58c2f512 merged into v1.x branch via PR #3451
2026-09-05
Patched releases v1.30.0 and v2.2.0 published to GitHub and PyPI
2026-09-05
GitHub Security Advisory GHSA-w4fh-qvv9-3v23 and CVE-2026-116684 officially published
2026-10-27

References & Sources

  • [1]GitHub Security Advisory GHSA-w4fh-qvv9-3v23
  • [2]NVD - CVE-2026-116684 Detail
  • [3]CVE.org - CVE-2026-116684 Record
  • [4]GitHub Pull Request #3447 (v2.x Fix)
  • [5]GitHub Pull Request #3451 (v1.x Backport)
  • [6]Fix Commit 0c9136841ff092987a20700ff9c2c9789bda2f40 (main / v2.x)
  • [7]Fix Commit 8c2fa6eabacde869d75568e33b9d466b58c2f512 (v1.x)
  • [8]Model Context Protocol Python SDK Release v1.30.0
  • [9]Model Context Protocol Python SDK Release v2.2.0
  • [10]CVE List V5 Record (CVE-2026-116684)

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 1 hour ago•CVE-2026-116686
6.5

CVE-2026-116686: Server-Side Request Forgery and Synchronous Denial of Service in Model Context Protocol Python SDK

CVE-2026-116686 is a Server-Side Request Forgery (SSRF) and Denial of Service (DoS) vulnerability in the official Model Context Protocol (MCP) Python SDK (mcp package on PyPI). When an MCP client validates structured tool execution results against a server-provided outputSchema, the SDK invokes the Python jsonschema library with its default URI resolution configuration. An untrusted or compromised MCP server can supply an outputSchema containing external $ref directives (using http://, https://, or file:// schemes), forcing the client process to synchronously fetch internal network resources, read local files, or block the main event loop indefinitely.

Amit Schendel
Amit Schendel
1 views•10 min read
•about 2 hours ago•CVE-2026-116685
5.9

CVE-2026-116685: Cross-Origin Redirect Credential and Request Payload Disclosure in MCP Python SDK

CVE-2026-116685 (GHSA-5h93-6whr-6q8j) is a sensitive information disclosure vulnerability in the official Model Context Protocol (MCP) Python SDK (`mcp` on PyPI). In versions 1.8.0 through 1.29.1 and 2.0.0 through 2.1.1, the SDK's HTTP-based client transports—including Streamable HTTP, Server-Sent Events (SSE), and OAuth client flows—unconditionally enable automatic HTTP redirect following (`follow_redirects=True`) across origin boundaries. When a configured endpoint returns a redirect to an external origin, the HTTP client forwards caller-supplied custom authentication headers (such as `X-API-Key`) and, in the case of HTTP 307 or 308 responses, replays the full POST request body containing JSON-RPC payloads or OAuth parameters to the untrusted destination.

Alon Barad
Alon Barad
4 views•11 min read
•about 3 hours ago•CVE-2026-116694
6.3

CVE-2026-116694: Unbounded Memory Allocation and Denial of Service in OpenTelemetry Python Jaeger Propagator

CVE-2026-116694 (GHSA-f5m9-jfrj-jjj7) is an unbounded resource allocation vulnerability (CWE-770) in the optional Jaeger propagator component (opentelemetry-propagator-jaeger) of the OpenTelemetry Python SDK prior to version 1.45.0. When extracting distributed tracing context from inbound carriers, JaegerPropagator.extract() processes all headers prefixed with 'uberctx-' without enforcing limits on entry count, per-entry byte size, or aggregate byte size. In environments where transport-level header constraints are absent, relaxed, or bypassed (such as non-HTTP message brokers, RPC frameworks, or web servers with elevated buffer configurations), an unauthenticated remote attacker can supply high-volume or oversized baggage headers to trigger excessive URL unquoting, short-lived immutable dictionary allocations, and CPU starvation.

Alon Barad
Alon Barad
3 views•10 min read
•about 5 hours ago•CVE-2026-116675
8.5

CVE-2026-116675: Stored Cross-Site Scripting in TinyMCE Media Plugin via Pre-Sanitization DOM Instantiation

CVE-2026-116675 is a stored Cross-Site Scripting (XSS) vulnerability in the TinyMCE rich text editor affecting versions 7.9.3 and 8.5.1 through 8.9.2. The flaw resides in the media plugin's serialization logic, where placeholder elements configured with the data-mce-object attribute are converted into real DOM elements using the active window's document context prior to sanitization. When an attacker supplies a media element with an invalid source attribute alongside an inline event handler attribute such as data-mce-p-onerror, the browser resolves the resource and executes the malicious JavaScript before the sanitizer can strip the dangerous attributes.

Alon Barad
Alon Barad
5 views•10 min read
•about 6 hours ago•CVE-2026-116693
8.7

CVE-2026-116693: Regular Expression Denial of Service in Datadog Node.js Tracer (dd-trace)

CVE-2026-116693 is a high-severity Regular Expression Denial of Service (ReDoS) vulnerability affecting the official Datadog Application Performance Monitoring (APM) client library for Node.js, dd-trace. The defect resides in the default regular expression defined by the DD_TRACE_OBFUSCATION_QUERY_STRING_REGEXP configuration parameter, which is used to sanitize incoming and outgoing HTTP URL query strings prior to recording trace span metadata. Due to overlapping sub-patterns and unanchored repetition blocks in the JSON Web Token (JWT) and URL-encoded string matching branches, the V8 JavaScript engine's regular expression subsystem (Irregexp) can be forced into catastrophic or high-degree polynomial backtracking. Because regular expression replacement occurs synchronously on the primary Node.js event loop, an unauthenticated remote attacker can send crafted HTTP requests with malicious query strings to consume 100% of the process CPU core, stalling concurrent request processing and rendering the application unavailable.

Alon Barad
Alon Barad
5 views•10 min read
•about 7 hours ago•CVE-2026-116692
9.8

CVE-2026-116692: Remote Code Execution in MLflow via Third-Party Scorer Deserialization

CVE-2026-116692 (GHSA-26p8-2jq9-3vq9) is a remote code execution vulnerability in MLflow affecting versions 3.12.0rc0 prior to 3.17.0. The flaw stems from an overly permissive module prefix check during the deserialization of third-party GenAI evaluation scorers in mlflow/genai/scorers/base.py. By setting an experiment's artifact root to a local package directory within the Python module search path and uploading a crafted Python file as a run artifact, an attacker can invoke the /ajax-api/3.0/mlflow/scorer/invoke endpoint to dynamically import and execute arbitrary code on the MLflow tracking server.

Amit Schendel
Amit Schendel
9 views•9 min read