GHSA-x227-pf99-vffg: PraisonAI: MCP SSE transport binds 0.0.0.0 with no authentication and no Origin validation; bundled SecurityConfig is never wired in
(updated )
The MCP SSE server started via ToolsMCPServer.run_sse() / launch_tools_mcp_server(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(sse_path, endpoint=handle_sse), # “/sse” Mount(messages_path, app=sse_transport.handle_post_message), # “/messages/” ]) uvicorn.run(app, host=host, port=port) - launch_tools_mcp_server also defaults host=“0.0.0.0” (line 301).
src/praisonai-agents/praisonaiagents/mcp/mcp_security.py defines but the transports never call:
- is_valid_origin (line 30), is_potential_dns_rebinding (line 110), validate_auth_header (line 167), SecurityConfig.is_origin_allowed (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: launch_tools_mcp_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 - run_sse(host=‘0.0.0.0’); launch_tools_mcp_server(host=‘0.0.0.0’) -> EXPOSED Check 2 - Starlette(…) kwargs: [‘debug’,‘routes’] -> NO middleware= (no auth/origin gate) Check 3 - is_valid_origin / is_potential_dns_rebinding / validate_auth_header / SecurityConfig never called by any transport -> DEAD CODE Live exploitation against a running server: curl -N http://VICTIM:8080/sse
References
Code Behaviors & Features
Detect and mitigate GHSA-x227-pf99-vffg with GitLab Dependency Scanning
Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Dependency Scanning using SBOM also detects vulnerabilities from proprietary advisories that this site does not include. Learn more about Dependency Scanning using SBOM →