Mastodon Mastodon Mastodon Mastodon

Official MCP Python SDK: malicious server could intercept client OAuth credentials

Photo of author

CyberSecureFox Editorial Team

Published:

A high-severity vulnerability has been discovered in the official Python SDK for the Model Context Protocol (MCP), an open standard for connecting AI applications to external tools and data. A malicious MCP server could redirect a client application’s OAuth credentials (client secret, authorization code, and PKCE verifier) to an endpoint controlled by the attacker, and then obtain a valid access token from the legitimate authorization server. Fixes were released in versions 1.30.0 and 2.2.0, but for two of the affected providers updating alone is not enough — an additional issuer= parameter must be configured.

Essence of the vulnerability and attack mechanism

According to the official security advisory (GHSA-qx49-fqc8-xw99), the issue stems from insufficient data authentication (CWE-345) and insufficient credential protection (CWE-522). When an MCP client initiates OAuth authentication, it requests authorization server information from the MCP server. In vulnerable versions, the SDK did not validate the response received, which allowed a malicious server to:

  • specify its own authorization server in the protected resource metadata;
  • not publish protected resource metadata at all, and instead provide metadata that names the legitimate authorization server as the issuer, while tokens are actually sent to the attacker’s endpoint.

As a result, the client would send the attacker the client_secret, the authorization code, and the PKCE verifier code_verifier — a one-time value intended to protect against replay of an intercepted authorization code. Sending the verifier completely neutralizes this protection. The client secret is long-lived and remains valid until it is forcibly rotated.

For the interactive OAuthClientProvider, the user still has to confirm the login, but as noted by Cycode, which discovered the vulnerability, the consent page is the genuine login page of the legitimate service — nothing looks suspicious. The two machine-to-machine providers (ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider) do not require any human involvement at all.

Affected versions and configurations

The vulnerable package is mcp (pip). Affected versions:

  • 1.9.1 — 1.29.1: no issuer verification or credential binding on any paths;
  • 2.0.0 — 2.1.1: checks are absent when using the legacy fallback path (when the server does not publish protected resource metadata) or when receiving a 403 insufficient_scope response;
  • All alpha versions from 2.0.0a1 up to but not including 2.2.0.

An application is vulnerable when both of the following conditions are met: it uses the SDK as an MCP client over HTTP with one of the OAuth handlers (OAuthClientProvider, ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider, or the legacy RFC7523OAuthClientProvider), and it can connect to an MCP server that the operator does not fully control, while holding credentials for a legitimate authorization server.

Not affected: MCP servers built on the SDK; clients using a local connection (stdio); clients that attach tokens or headers themselves.

Severity assessment

The advisory assigns a score of CVSS 7.5 (High) for providers that operate without human involvement. For the interactive OAuthClientProvider, which requires user confirmation, the score is 6.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N). At the time the advisory was published, no CVE identifier had been assigned.

Neither the security advisory nor the Cycode report contain information about active exploitation of the vulnerability.

Impact assessment

The vulnerability poses the greatest risk to organizations deploying MCP-based AI applications that connect to third-party MCP servers over HTTP and use OAuth for authentication. The machine-to-machine provider scenario is particularly critical: the attack is fully automated and does not require social engineering. The access token obtained by the attacker inherits all permissions granted to the application, which may lead to full compromise of the account on the side of the legitimate service.

Mitigation recommendations

Updating the package is a necessary but not always sufficient step. The complete action plan:

  1. Update the package to version 1.30.0 (1.x branch) or version 2.2.0 (2.x branch). In the fixed versions, the client determines the expected authorization server before receiving any metadata and rejects mismatches.
  2. For ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider, you must pass the issuer= parameter with the address of the legitimate authorization server (for example, issuer="https://auth.example.com"). Without this parameter, the updated providers will still follow the authorization server specified by the MCP server. In version 1.30.0, the warning about a missing issuer= is emitted as a standard deprecation warning, which Python hides by default — it is easy to miss.
  3. The legacy RFC7523OAuthClientProvider does not support the issuer= parameter. You need to switch to one of the other two providers.
  4. Clear stored OAuth registrations once after updating. Registrations created before the fix are not bound to a specific authorization server and remain in that state.
  5. If the client may have connected to an untrusted MCP server, rotate the client secret and revoke its tokens on the authorization server side.

For versions older than the fixed ones, the only measure is to connect OAuth clients exclusively to trusted MCP servers.

Disclosure timeline

Fixes with issuer verification were included in releases 1.30.0 and 2.2.0 dated 7 September 2026 and were described in the release notes as a behavior change rather than a security fix. The security advisory was published on 28 September — the same day Cycode released its analysis. The advisory lists eight people who reported the issue, including the Cycode researcher.

Organizations using the MCP Python SDK for HTTP clients with OAuth authentication should immediately update the package to version 1.30.0 or 2.2.0, ensure that the issuer= parameter is set for machine-to-machine providers, clear old registrations, and, if compromise is suspected, rotate secrets. The three-week gap between the release of the patch and publication of the advisory means that some users may have updated without realizing the critical nature of the change.


CyberSecureFox Editorial Team

The CyberSecureFox Editorial Team covers cybersecurity news, vulnerabilities, malware campaigns, ransomware activity, AI security, cloud security, and vendor security advisories. Articles are prepared using official advisories, CVE/NVD data, CISA alerts, vendor publications, and public research reports. Content is reviewed before publication and updated when new information becomes available.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.