Critical OAuth Flaw in MCP Python SDK Exposes AI App Credentials
A significant vulnerability has been discovered in the official **Model Context Protocol (MCP) Python SDK**, potentially allowing malicious **MCP** servers to steal OAuth credentials from AI applications. The flaw, rated high severity, enables attackers to gain access tokens with the same permissions as the compromised application, posing a substantial risk to identity security in AI integrations.

The maintainers of the official **MCP Python SDK** have issued a security advisory regarding a critical flaw that could lead to the compromise of OAuth credentials in applications built using the SDK. A malicious **MCP** server could trick an application into divulging its client secret, authorization code, and **PKCE** proof key to an attacker-controlled token endpoint.
### The Vulnerability Explained
The **Model Context Protocol (MCP)** is an open standard designed to facilitate the connection of AI applications with external tools and data. The affected versions of its Python SDK failed to adequately validate the authorization server's location provided by an **MCP** server. This oversight allows a malicious server to redirect the client to an attacker's chosen login service, or to a legitimate login service while intercepting the credentials.
Security firm **Cycode**, which reported the flaw, demonstrated that the stolen credentials could be used to request a valid access token from the real login service. This token would carry all the permissions granted to the application, and since the client secret is long-lived, it remains active until manually rotated.
The flaw is rated 7.5 (high severity) for machine-to-machine providers that operate without human intervention, and 6.5 for interactive providers where user approval is required. As of September 29, no **CVE** had been assigned.
### How Credentials Are Stolen
When an **MCP** client initiates a login, it queries the connected server for its authorization server's location. In vulnerable SDK versions, this response was not sufficiently verified. A malicious **MCP** server could therefore provide a fraudulent endpoint, causing the client to send its client secret, authorization code, and **PKCE** proof key directly to the attacker instead of the legitimate service. The compromise of the **PKCE** proof key is particularly concerning, as it defeats a key protection mechanism designed to prevent the reuse of stolen authorization codes.
Even with interactive providers, where a user must approve the sign-in, the exploit remains effective. **Cycode** notes that the approval page presented to the user appears genuine, masking the underlying credential theft. For machine-to-machine providers, no user interaction is necessary, making the attack seamless.
### Affected Versions and Mitigation
Applications are vulnerable if they use the **MCP Python SDK** as a client over HTTP with one of the following OAuth providers: `OAuthClientProvider`, `ClientCredentialsOAuthProvider`, `PrivateKeyJWTOAuthProvider`, or the deprecated 1.x `RFC7523OAuthClientProvider`. This applies specifically when the application can connect to an untrusted server while holding credentials for a real login service. **MCP** servers built with the SDK, local (stdio) clients, and clients using their own tokens are not affected.
| Line | Affected | Fixed in |
| :--- | :------------------- | :------- |
| 1.x | 1.9.1 through 1.29.1 | 1.30.0 |
| 2.x | 2.0.0 through 2.1.1 | 2.2.0 |
### Recommended Actions
All users are urged to upgrade to version **1.30.0** for the 1.x line or **2.2.0** for the 2.x line of the **MCP Python SDK**. These fixed versions introduce client-side checks to verify the expected login service before fetching details, rejecting any discrepancies.
For users of `ClientCredentialsOAuthProvider` or `PrivateKeyJWTOAuthProvider`, upgrading alone is not sufficient. The advisory explicitly states that users must also pass `issuer=` to name the login service associated with those credentials. Failing to do so will still allow the client to follow whichever server the **MCP** server points it at. It's important to note that on version 1.30.0, the warning about this requirement is a standard Python deprecation warning, which might be hidden by default. The deprecated `RFC7523OAuthClientProvider` lacks an `issuer=` option entirely, necessitating a migration to one of the other two providers.
After upgrading, it is crucial to clear any stored OAuth client registrations once, as older registrations are not tied to a login service. If there is a possibility that a client has already connected to an untrusted server, users should immediately rotate their client secret and revoke any compromised tokens at the login service. For those unable to upgrade, the only workaround is to connect solely to trusted **MCP** servers.
### Disclosure Timeline
The issuer checks were initially included in the 1.30.0 and 2.2.0 release notes on September 7, described as behavior changes rather than a security fix. The official security advisory was subsequently published on September 28, coinciding with **Cycode**'s public writeup. The advisory credits eight reporters, including **Cycode**'s researcher. No attacks leveraging this flaw have been reported by either the advisory or **Cycode** at the time of publication.