Skip to content
fastmcpGHSA-mxxr-jv3v-6pgc

FastMCP vulnerable to reflected XSS in client's callback page

MediumCVE-2025-62800 · Published Oct 29, 2025 · updated Jul 7, 2026

### Summary While setting up an oauth client, it was noticed that the callback page hosted by the client during the flow embeds user-controlled content without escaping or sanitizing it. This leads to a reflected Cross-Site-Scripting vulnerability. ### Details The affected code is located in *https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/oauth_callback.py*, which embeds all values passed to the `create_callback_html` function via the `message` parameter it into the callback page without escaping them. This can, for example, be abused by calling the callback server with an XSS payload inside the `error` GET parameter, the value of which will then be inserted into the callback page, causing the execution of attacker-controlled JavaScript code in the callback server's origin. Note that besides the `error` parameter, other parameters reaching this function are affected too. ### PoC 1. Setup a simple fastmcp client such as this one (the callback server's port was fixated for simplicity): ``` url="http://127.0.0.1:8000/mcp" oauth = OAuth(mcp_url=url,callback_port=1337) async def main(): async with Client(url, auth=oauth) as client: await client.ping() ...

GitHub advisory

Affected versions

PackageAffectedFixed in
fastmcp
PyPI
< 2.13.02.13.0
Details and references

### Summary While setting up an oauth client, it was noticed that the callback page hosted by the client during the flow embeds user-controlled content without escaping or sanitizing it. This leads to a reflected Cross-Site-Scripting vulnerability. ### Details The affected code is located in *https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/client/oauth_callback.py*, which embeds all values passed to the `create_callback_html` function via the `message` parameter it into the callback page without escaping them. This can, for example, be abused by calling the callback server with an XSS payload inside the `error` GET parameter, the value of which will then be inserted into the callback page, causing the execution of attacker-controlled JavaScript code in the callback server's origin. Note that besides the `error` parameter, other parameters reaching this function are affected too. ### PoC 1. Setup a simple fastmcp client such as this one (the callback server's port was fixated for simplicity): ``` url="http://127.0.0.1:8000/mcp" oauth = OAuth(mcp_url=url,callback_port=1337) async def main(): async with Client(url, auth=oauth) as client: await client.ping() # List available operations tools = await client.list_tools() print(f"tools: {tools}") asyncio.run(main()) ``` 2. Ensure that the MCP server located at `http://127.0.0.1:8000/mcp` supports oauth. 3. Start the client. 4. As soon as the callback server has been started, access `http://localhost:1337/callback?error=<img/src/onerror=alert(window.origin)>` Note that the exploitation could also for example be initiated by a malicious authorization server by returning the exploitation URL mentioned before in the `authorization_endpoint` field. The client would then automatically open, causing the XSS to trigger immediatly. ### Impact The impact of this XSS vulnerability is the arbitrary JavaScript execution in the victim's browser in the callback server's origin.

CVSS 4.0
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N
Severity from
GitHub (reviewed advisory)
Weakness
CWE-79
Also known as
CVE-2025-62800, PYSEC-2026-1364

More fastmcp advisories

All fastmcp

Critical advisories by email

Wednesdays: the week’s critical and high advisories in the AI and data stack, with the fixed versions. Only in weeks that have some.

Double opt-in. Unsubscribe any time.