Skip to content

Security Independently confirmed2 publishers 3 min read Published Updated

Two MCP Python SDK OAuth providers stay exposed after upgrade until code names an issuer

MCP Python SDK maintainers fixed a flaw rated up to 7.5 that lets malicious servers steal OAuth client secrets, in versions 1.30.0 and 2.2.0. Two of the affected providers stay exposed after upgrading until the calling code passes issuer=.

The Watch · Security desk

Send a correction

What happened

  • Cycode, which reported the flaw, used the stolen material in a test to get a valid access token from the real login service.
  • The issuer checks shipped on September 7 as behavior changes, and the security advisory followed 21 days later, on September 28.
  • Neither the advisory nor Cycode reports attacks using the flaw, and none has been reported elsewhere.

Why it matters

  • Who's exposed exposure A service on ClientCredentialsOAuthProvider or PrivateKeyJWTOAuthProvider can be upgraded to 1.30.0 and still follow a hostile server, and its only warning is a deprecation notice Python hides by default.
  • Who has to decide decision Deciding who rotates takes a record of which MCP servers each client has reached. A team without that record cannot rule out that a secret has already left.
  • What it limits constraint Teams that cannot upgrade yet have to keep their clients away from every MCP server they do not trust, because older releases have no other workaround.

To use the flaw, an attacker has to get a victim client to connect to a server the attacker runs [1]. That client must use the SDK over HTTP with one of four OAuth providers: OAuthClientProvider, ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider, or the deprecated 1.x RFC7523OAuthClientProvider [19]. It must also hold credentials for a real login service while connecting to a server it does not fully control [19]. The machine-to-machine providers need no sign-in and no person at all [10]. With the interactive provider someone has to approve a sign-in, but Cycode says the page they approve is the genuine login page, so nothing looks wrong [9]. The scores follow that split: 7.5 for the providers that run without a person present, 6.5 for the interactive one [6].

The theft happens at discovery. A client that needs to log in asks the MCP server where its authorization server can be found, and affected versions did not always check the answer [7]. A hostile server can name its own login service outright. It can also serve login details that name the user's real service while sending the credentials elsewhere [7]. Either way the PKCE proof key goes out with the authorization code [2]. That key is a one-time value meant to stop a stolen code from being reused, so handing it over removes that protection too [8]. The access token Cycode obtained in its test carried whatever permissions the app had been granted [4].

Fixed versions work out which login service they expect before fetching any details, and refuse any that name a different one [11]. For ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider, the advisory says "upgrading changes nothing until you also pass issuer=" [12]. Without that argument, both still follow whichever server the MCP server points them at [12]. RFC7523OAuthClientProvider has no issuer= option, so code on it has to move to one of the other two [14]. OAuth client registrations stored before the upgrade are not tied to a login service and stay that way until they are cleared once [15].

The client secret is long-lived and keeps working until it is changed [5]. The advisory lists rotation as a separate step from upgrading: rotate the secret and revoke tokens at the login service if a client may already have connected to an untrusted server [16]. SDK-built MCP servers, local stdio clients and clients that attach their own tokens are outside the flaw [20]. On that evidence, the clients that need a new secret are HTTP clients on the four affected providers that may have reached a server their owners do not fully control [25].

No CVE had been assigned as of September 29 [18]. The advisory credits eight reporters, Cycode's researcher among them [23].

What to watch

  • Whether a CVE is assigned; none existed as of September 29.
  • Any report of the flaw being used against a real deployment; the advisory and Cycode report none so far.
  • Whether a later release makes the issuer check the default for ClientCredentialsOAuthProvider and PrivateKeyJWTOAuthProvider, or raises the warning above a hidden deprecation notice.

Clarity's read

What the record supports and how the coverage leans. The claims behind it follow.

Reality

Evidence72
Adoption
Not scored
Hype gap0
Incentives30
Confidence70
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [1]

    A malicious MCP server could trick an application built on the official MCP Python SDK into handing over the OAuth credentials it uses to log in to a real service, according to the SDK maintainers' security advisory.

    Reported Supported Source: SDK maintainers' advisory, via The Hacker NewsView cited source
  2. [2]

    Affected versions sent the client secret, the authorization code, and the PKCE proof key to a token endpoint the attacker controlled.

    Reported SupportedView cited source
  3. [3]

    The fix is in MCP Python SDK versions 1.30.0 and 2.2.0.

    Reported SupportedView cited source
  4. [4]

    Cycode, the security firm that reported the flaw, demonstrated in a test that the stolen credentials can be used to request a valid access token from the real login service; the resulting token carries whatever permissions the app was granted.

    Reported Supported Source: CycodeView cited source
  5. [5]

    The client secret is long-lived, so it keeps working until it is changed.

    Reported SupportedView cited source
  6. [6]

    The flaw is rated high (7.5) for the two providers that run without a person present, and 6.5 for the interactive provider.

    Reported SupportedView cited source
  7. [7]

    An MCP client needing to log in asks the server it connects to where its authorization server is; affected SDK versions did not always check that answer, so a malicious server could name the attacker's own server or serve login details naming the user's real service while sending the credentials elsewhere.

    Reported SupportedView cited source
  8. [8]

    The PKCE proof key is a one-time value designed to prevent a stolen authorization code from being reused, so handing it over defeats that protection.

    Reported SupportedView cited source
  9. [9]

    With the interactive provider a person still has to approve a sign-in; Cycode says the page they approve is the genuine login page, so nothing looks wrong.

    Reported Supported Source: CycodeView cited source
  10. [10]

    The two machine-to-machine providers need no sign-in and no person at all.

    Reported SupportedView cited source
  11. [11]

    In the fixed versions, the client works out which login service it expects before fetching any details and refuses any that name a different one.

    Reported SupportedView cited source
  12. [12]

    For ClientCredentialsOAuthProvider or PrivateKeyJWTOAuthProvider, the advisory says "upgrading changes nothing until you also pass issuer="; without it, they still follow whichever server the MCP server points them at.

    Reported Supported Source: SDK security advisoryView cited source
  13. [13]

    On 1.30.0, the warning about the missing issuer= is a standard deprecation warning, which Python hides by default.

    Reported SupportedView cited source
  14. [14]

    The deprecated RFC7523OAuthClientProvider has no issuer= option, so users should move to one of the other two providers.

    Reported SupportedView cited source
  15. [15]

    After upgrading, stored OAuth client registrations should be cleared once, because older ones are not tied to a login service and stay that way.

    Reported SupportedView cited source
  16. [16]

    If a client may already have connected to an untrusted server, its client secret should be rotated and its tokens revoked at the login service.

    Reported SupportedView cited source
  17. [17]

    On older versions there is no workaround other than connecting only to MCP servers you trust.

    Reported SupportedView cited source
  18. [18]

    No CVE had been assigned as of September 29.

    Reported SupportedView cited source
  19. [19]

    An application is affected if it uses the SDK as an MCP client over HTTP with OAuthClientProvider, ClientCredentialsOAuthProvider, PrivateKeyJWTOAuthProvider, or the deprecated 1.x RFC7523OAuthClientProvider, and can connect to a server it does not fully control while holding credentials for a real login service.

    Reported SupportedView cited source
  20. [20]

    MCP servers built with the SDK, local (stdio) clients, and clients that attach their own tokens are not affected.

    Reported SupportedView cited source
  21. [21]

    The issuer checks shipped in the 1.30.0 and 2.2.0 release notes on September 7, listed under behavior changes rather than as a security fix.

    Reported SupportedView cited source
  22. [22]

    The security advisory followed on September 28, the same day Cycode published its writeup.

    Reported SupportedView cited source
  23. [23]

    The advisory credits eight reporters, including Cycode's researcher.

    Reported SupportedView cited source
  24. [24]

    Neither the advisory nor Cycode reports any attacks using the flaw, and none has been reported elsewhere.

    Reported SupportedView cited source
  25. [25]

    The clients that need a rotated secret are HTTP clients on the four affected OAuth providers that may have connected to a server their owners do not fully control.

    Derived Supported
  26. [26]

    The security advisory came 21 days after the issuer checks shipped as behavior changes.

    Derived Supported

Sources

2 independent publishers whose own reporting we read for this story.

  1. dev.to

    1 article · October 1, 2026

    What Is the MCP Python SDK OAuth Flaw? (Sept 29, 2026)
  2. thehackernews.com

    2 articles · September 29, 2026

    Official MCP Python SDK Flaw Can Let Malicious Servers Steal OAuth Credentials

Topics and entities

Topics