GHSA-x227-pf99-vffg CVE-2026-57123 PYSEC-2026-3536
PraisonAI: MCP SSE transport binds 0.0.0.0 with no authentication and no Origin validation; bundled SecurityConfig is never wired in
- Severity
- 9.8 / 10
- Critical · CVSS 3.1
- Exploit chance (EPSS)
- 0.90%
- Chance of exploitation in the next 30 days. Higher than 59.81% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-1327 Binding to an Unrestricted IP Address
- CWE-306 Missing Authentication for Critical Function
- CWE-350 Reliance on Reverse DNS Resolution for a Security-Critical Action
- Fix
1.6.59- Upgrade praisonaiagents to this version or later
Description
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)
- no
- 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=<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 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).
Affected versions
PyPI
| Package | Vulnerable | Fixed in |
|---|---|---|
| praisonaiagents | < 1.6.59 |
1.6.59 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
praisonaiagents PyPI → 1.6.59
- pip
pip install --upgrade "praisonaiagents>=1.6.59"- poetry
poetry add "praisonaiagents>=1.6.59"- uv
uv add "praisonaiagents>=1.6.59"
Severity breakdown
CVSS 3.1 9.8
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- None
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- High
- Integrity
- High
- Availability
- High
Weakness
CWE-1327: Binding to an Unrestricted IP Address
The product assigns the address 0.0.0.0 for a database server, a cloud service/instance, or any computing resource that communicates remotely.
How to prevent it
- System Configuration: Assign IP addresses that are not 0.0.0.0.
- System Configuration: Unwanted connections to the configured server may be denied through a firewall or other packet filtering measures.
CWE-306: Missing Authentication for Critical Function
The product does not perform any authentication for functionality that requires a provable user identity or consumes a significant amount of resources.
How to prevent it
- Architecture and Design: Divide the software into anonymous, normal, privileged, and administrative areas. Identify which of these areas require a proven user identity, and use a centralized authentication capability. Identify all potential communication channels, or other means of interaction with the software, to ensure that all channels are appropriately protected, including those channels that are assumed to be accessible only by authorized parties. Developers sometimes perform authentication at the primary channel, but open up a secondary channel that is assumed to be private. For example, a login mechanism may be listening on one network port, but after successful authentication, it may open up a second port where it waits for the connection, but avoids authentication because it assumes that only the authenticated party will connect to the port. In general, if the software or protocol allows a single session or user state to persist across multiple connections or channels, authentication and appropriate credential management need to be used throughout.
- Architecture and Design: For any security checks that are performed on the client side, ensure that these checks are duplicated on the server side, in order to avoid CWE-602. Attackers can bypass the client-side checks by modifying values after the checks have been performed, or by changing the client to remove the client-side checks entirely. Then, these modified values would be submitted to the server.
- Architecture and Design: Where possible, avoid implementing custom, "grow-your-own" authentication routines and consider using authentication capabilities as provided by the surrounding framework, operating system, or environment. These capabilities may avoid common weaknesses that are unique to authentication; support automatic auditing and tracking; and make it easier to provide a clear separation between authentication tasks and authorization tasks. In environments such as the World Wide Web, the line between authentication and authorization is sometimes blurred. If custom authentication routines are required instead of those provided by the server, then these routines must be applied to every single page, since these pages could be requested directly.
- Architecture and Design: Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, consider using libraries with authentication capabilities such as OpenSSL or the ESAPI Authenticator [REF-45].
- Implementation, System Configuration, Operation: When storing data in the cloud (e.g., S3 buckets, Azure blobs, Google Cloud Storage, etc.), use the provider's controls to require strong authentication for users who should be allowed to access the data [REF-1297] [REF-1298] [REF-1302].
CWE-350: Reliance on Reverse DNS Resolution for a Security-Critical Action
The product performs reverse DNS resolution on an IP address to obtain the hostname and make a security decision, but it does not properly ensure that the IP address is truly associated with the hostname.
How to prevent it
- Architecture and Design: Use other means of identity verification that cannot be simply spoofed. Possibilities include a username/password or certificate.
- Implementation: Perform proper forward and reverse DNS lookups to detect DNS spoofing.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-gxmw-5f7x-6g22 praisonaiagents vulnerable to arbitrary file write via unsanitized `user_id` in `FileMemory.__init__()` — path traversal to any writable location | High | Also affects praisonaiagents |
| GHSA-cfxv-8fw8-rwpv praisonaiagents: ast_grep_rewrite rewrites arbitrary files without the @require_approval gate enforced on every sibling mutation tool | Medium | Also affects praisonaiagents |
| GHSA-x44h-65qv-cw74 praisonaiagents has an SSRF protection bypass in `spider_tools._host_is_blocked()` via DNS-resolved hostnames (`127.0.0.1.nip.io`) | High | Also affects praisonaiagents |
| GHSA-7g3p-92qq-8wvh praisonaiagents: AgentServer declares auth_token but never enforces it on any route | High | Also affects praisonaiagents |
| GHSA-5r34-2g38-6569 praisonaiagents web_crawl vulnerable to SSRF via redirect-following | High | Also affects praisonaiagents |
| GHSA-vg6p-v9vm-6fgj praisonaiagents vulnerable to SSRF in web_crawl tool via redirect-following and DNS rebinding (validate-then-fetch gap) | High | Also affects praisonaiagents |
| GHSA-8hjw-25cg-g52h praisonaiagents has a `web_crawl` SSRF protection bypass via unchecked redirect targets | High | Also affects praisonaiagents |
| GHSA-hxmv-c4g6-5fqc PraisonAI workflow include bypasses tools.py autoload opt-in and executes included recipe code | High | Also affects praisonaiagents |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor