MCP · CVE-2026-115563 · Package
FIX → 2.2.0 · 1.30.0
The MCP Python SDK's OAuth client did not check the authorization server issuer or bind stored client credentials to it, so a malicious or compromised MCP server could redirect the client's client_secret, authorization code, PKCE verifier or client assertion to a token endpoint it controls. Affected applications may lose the credentials they hold for a legitimate authorization server.
first public Sep 28, 2026 · 1 source
Could this affect your app?
Free first check from your website. Connect your repo for the full answer.
Applications that use the MCP Python SDK as an HTTP client with an OAuth provider and hold credentials for a real authorization server, and that may connect to an MCP server they do not fully trust. MCP servers built with the SDK, stdio clients, and clients that attach their own tokens or headers are not affected.
Not affected if mcp-server-only, own-tokens-or-headers, stdio-transport, trusted-mcp-servers-only
Who cares mcp, oauth, python
pip show mcp (or uv pip show mcp) and compare the version against the affected ranges: 1.9.1 through 1.29.1, and 2.0.0 through 2.1.1.In affected versions, the SDK's OAuth client support (mcp.client.auth) let the MCP server a client connected to decide where the client's OAuth credentials were sent:
issuer was not validated on every discovery path, andA malicious or compromised MCP server could therefore direct them to a token endpoint of its choosing:
issuer.It would then receive the client_secret, authorization code and PKCE code_verifier meant for that real server (or, with PrivateKeyJWTOAuthProvider, a signed client assertion).
Yes, if both of these hold:
OAuthClientProvider, , or the deprecated 1.x as the transport's handler;Check it with your coding agent
It reads this page and tells you if your code is affected.
Are you affected?
Ask from here. InfraStack checks the affected versions against your stack and answers in your inbox.
InfraStack checks the affected versions against your stack and answers in Slack, with the evidence and the fix.
OAuthClientProviderClientCredentialsOAuthProviderPrivateKeyJWTOAuthProviderRFC7523OAuthClientProviderauthUpgrade to 2.2.0 · 1.30.0
mcp 2.x: upgrade to 2.2.0 or later.mcp 1.x: upgrade to 1.30.0 or later.ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider, also pass issuer= (for example issuer="https://auth.example.com"); upgrading alone does not bind credentials to the issuer.RFC7523OAuthClientProvider has no issuer option; move to one of the two providers above.ClientCredentialsOAuthProviderPrivateKeyJWTOAuthProviderRFC7523OAuthClientProviderauthAffected versions:
issuer check and no credential binding on any path.403 insufficient_scope.ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider had no way to name the authorization server their credentials belong to.Not affected:
The rating is scored for the unattended providers. With the interactive OAuthClientProvider a person has to start the sign-in; scored that way it is 6.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N).
Upgrade to mcp 2.2.0 (2.x) or 1.30.0 (1.x) or later.
If you use ClientCredentialsOAuthProvider or PrivateKeyJWTOAuthProvider, upgrading changes nothing until you also pass issuer= (for example issuer="https://auth.example.com"):
DeprecationWarning, which Python hides by default.RFC7523OAuthClientProvider has no issuer option. Move to one of these two providers.In the fixed versions the client also:
issuer differs, with OAuthFlowError;After upgrading:
issuer on that record instead.On earlier versions there is no workaround other than connecting OAuth-enabled clients only to MCP servers you trust.