PT-2026-53152 · Pypi · Praisonaiagents
Publicado
2026-06-18
·
Atualizado
2026-06-18
CVSS v3.1
9.8
Crítica
| Vetor | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
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
event: endpoint / data: /messages/?session id=
curl -X POST "http://VICTIM:8080/messages/?session id=" -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=" -H 'Content-Type: application/json'
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"","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 is valid origin / is potential dns rebinding; reject bad origins.
- Enforce validate auth header when SecurityConfig.require auth; default require auth=True (and allow missing origin=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).
Correção
Missing Authentication
Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾
Identificadores relacionados
Produtos afetados
Praisonaiagents