GHSA-x227-pf99-vffg
The MCP SSE server started via ToolsMCPServer.runsse() / launchtoolsmcpserver(transport="sse")
binds to 0.0.0.0 by default and builds its Starlette application with no authentication middleware
and no Origin-header validation. The module mcp/mcp_security.py provides exactly the needed controls
(origin validation, DNS-rebinding detection, auth-header enforcement, a SecurityConfig), but none of
these functions are ever called by any transport — they are dead code. Any host that can reach the
port can list and invoke every registered tool with no credentials, and a victim's browser can drive
the same calls against a localhost instance via DNS rebinding.
Affected code: src/praisonai-agents/praisonaiagents/mcp/mcp_server.py
- run_sse defaults host to all interfaces (line 245) and builds the app with only
debugandroutes - no
middleware=and no per-route auth/origin gate (lines ~271-289):
app = Starlette(debug=self._debug, routes=[
Route(ssepath, endpoint=handlesse), # "/sse"
Mount(messagespath, app=ssetransport.handlepostmessage), # "/messages/"
])
uvicorn.run(app, host=host, port=port)
- launchtoolsmcp_server also defaults host="0.0.0.0" (line 301).
src/praisonai-agents/praisonaiagents/mcp/mcp_security.py defines but the transports never call:
- isvalidorigin (line 30), ispotentialdnsrebinding (line 110), validateauth_header (line 167),
SecurityConfig.isoriginallowed (line 236). These symbols are referenced only inside mcp_security.py
and the init re-export. (mcp_websocket.py's auth references are CLIENT-side, not server validation.)
Impact:
launchtoolsmcp_server(transport="sse") is the documented path for exposing tools over MCP. With the
defaults above it is an unauthenticated, network-reachable tool-execution endpoint. Blast radius equals
the capabilities of the registered tools; with file/shell/code-exec tools this is RCE. With no Origin
check, a malicious page the victim merely visits can rebind its hostname to 127.0.0.1 and issue the
JSON-RPC calls cross-origin against a developer's local server.
Proof of concept:
Static proof (AST analysis of unmodified source):
Check 1 - runsse(host='0.0.0.0'); launchtoolsmcpserver(host='0.0.0.0') -> EXPOSED
Check 2 - Starlette(...) kwargs: ['debug','routes'] -> NO middleware= (no auth/origin gate)
Check 3 - isvalidorigin / ispotentialdnsrebinding / validateauth_header / SecurityConfig
never called by any transport -> DEAD CODE
Live exploitation against a running server:
curl -N http://VICTIM:8080/sse
# event: endpoint / data: /messages/?session_id=<sid>
curl -X POST "http://VICTIM:8080/messages/?session_id=<sid>" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05",
"capabilities":{},"clientInfo":{"name":"x","version":"1"}}}'
curl -X POST "http://VICTIM:8080/messages/?session_id=<sid>" -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"<tool>","arguments":{...}}}'
No Authorization header anywhere. Browser DNS-rebinding variant drives the same calls cross-origin.
Remediation:
Wire in the existing mcp_security.py controls and fix defaults:
- Default run_sse(host="127.0.0.1"); require explicit opt-in to bind 0.0.0.0.
- Attach Starlette middleware calling isvalidorigin / ispotentialdns_rebinding; reject bad origins.
- Enforce validateauthheader when SecurityConfig.requireauth; default requireauth=True (and
allowmissingorigin=False) for any non-loopback bind.
Distinct from prior advisories:
The accepted MCP advisories are tool-handler bugs — tools/call path traversal -> .pth RCE
(GHSA-9mqq-jqxf-grvw) and unauthenticated file read via workflow.show/validate (GHSA-9cr9-25q5-8prj).
This is a transport-layer missing-auth/exposure: the SSE server never enforces auth or Origin validation
and ignores the security module the codebase ships. Closest in spirit to the default-insecure pattern
(GHSA-8444 / 86qc) but a different server and a different root cause (unwired controls, not an unset env var).
Package Versions Affected
Automatically patch vulnerabilities without upgrading
CVSS Version



Related Resources
References
https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-x227-pf99-vffg, https://github.com/MervinPraison/PraisonAI