{"id":"PYSEC-2026-1364","summary":"FastMCP vulnerable to reflected XSS in client's callback page","details":"### Summary\nWhile 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.\n\n### Details\nThe 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.\n\n### PoC\n1. Setup a simple fastmcp client such as this one (the callback server's port was fixated for simplicity):\n\n```\nurl=\"http://127.0.0.1:8000/mcp\"\noauth = OAuth(mcp_url=url,callback_port=1337)\n\nasync def main():\n    async with Client(url, auth=oauth) as client:\n        await client.ping()\n        \n        # List available operations\n        tools = await client.list_tools()\n\n        print(f\"tools: {tools}\")\n       \nasyncio.run(main())\n```\n\n2. Ensure that the MCP server located at `http://127.0.0.1:8000/mcp` supports oauth.\n3. Start the client.\n4. As soon as the callback server has been started, access `http://localhost:1337/callback?error=\u003cimg/src/onerror=alert(window.origin)\u003e`\n\nNote 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.\n\n### Impact\nThe impact of this XSS vulnerability is the arbitrary JavaScript execution in the victim's browser in the callback server's origin.","aliases":["CVE-2025-62800","GHSA-mxxr-jv3v-6pgc"],"modified":"2026-07-07T17:47:12.914598102Z","published":"2026-07-07T16:03:08.608105Z","references":[{"type":"WEB","url":"https://github.com/jlowin/fastmcp/security/advisories/GHSA-mxxr-jv3v-6pgc"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2025-62800"},{"type":"WEB","url":"https://github.com/jlowin/fastmcp/pull/2090"},{"type":"WEB","url":"https://github.com/jlowin/fastmcp/commit/2a20f54617a37213ed83894a8c2f0ac38a2e83a3"},{"type":"PACKAGE","url":"https://github.com/jlowin/fastmcp"},{"type":"PACKAGE","url":"https://pypi.org/project/fastmcp"},{"type":"ADVISORY","url":"https://github.com/advisories/GHSA-mxxr-jv3v-6pgc"}],"affected":[{"package":{"name":"fastmcp","ecosystem":"PyPI","purl":"pkg:pypi/fastmcp"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.13.0"}]}],"versions":["0.1.0","0.2.0","0.3.0","0.3.1","0.3.2","0.3.3","0.3.4","0.3.5","0.4.0","0.4.1","1.0","2.0.0","2.1.0","2.1.1","2.1.2","2.10.0","2.10.1","2.10.2","2.10.3","2.10.4","2.10.5","2.10.6","2.11.0","2.11.1","2.11.2","2.11.3","2.12.0","2.12.0rc1","2.12.1","2.12.2","2.12.3","2.12.4","2.12.5","2.13.0rc1","2.13.0rc2","2.13.0rc3","2.2.0","2.2.1","2.2.10","2.2.2","2.2.3","2.2.4","2.2.5","2.2.6","2.2.7","2.2.8","2.2.9","2.3.0","2.3.0rc1","2.3.1","2.3.2","2.3.3","2.3.4","2.3.5","2.4.0","2.5.0","2.5.1","2.5.2","2.6.0","2.6.1","2.7.0","2.7.1","2.8.0","2.8.1","2.9.0","2.9.1","2.9.2"],"database_specific":{"source":"https://github.com/pypa/advisory-database/blob/main/vulns/fastmcp/PYSEC-2026-1364.yaml"}}],"schema_version":"1.7.5","severity":[{"type":"CVSS_V4","score":"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"}]}