# PraisonAI Browser Server allows unauthenticated WebSocket clients to hijack connected extension sessions

PraisonAI browser bridge binds 0.0.0.0 and accepts Origin-less WebSocket clients, letting unauthenticated attackers start sessions and receive hijacked extension automation output.

- Payout: Research
- Severity: critical
- Program: PraisonAI
- Found by: R1ZZG0D
- Disclosed: 2026-04-10
- CVE: CVE-2026-40289
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-8x8f-54wf-vv92
- Library page: http://bugbountylibrary.com/r/ghsa%3AGHSA-8x8f-54wf-vv92
- Tags: area:ai domain:ai domain:web impact:data-leak impact:internal-access kind:research platform:ghsa sev:critical tech:python tech:websocket technique:source-review vuln:access-control vuln:auth-bypass

**Target:** Browser automation WebSocket bridge (/ws endpoint)
**Root cause:** Origin validation only runs when an Origin header is present, and start_session routes to the first idle connection without authenticating the controller, so any network client can impersonate a controller.
**Steps:**
1. Start `praisonai browser start` (default binds 0.0.0.0).
2. Connect a WebSocket to `/ws` with `Origin: chrome-extension://<32-char-id>` as the extension.
3. Connect a second WebSocket to `/ws` with no Origin header (accepted).
4. Send `{"type":"start_session","goal":"...","model":"dummy","max_steps":1}` from the Origin-less client.
5. Server forwards `start_automation` to the extension connection and assigns the session_id.
6. Extension sends `{"type":"observation","session_id":...,"step_number":1,...}`; server broadcasts `action` and `status` back to the unauthenticated client.
**How found:** Reporter read the handshake code and noticed origin checks were gated behind `if origin:`, then traced start_session routing to the first idle connection and the broadcast loop keyed only on session_id.
**Exploitation:** Attacker on the network connects to the exposed bridge without credentials, starts a session that gets forwarded to a connected extension, and receives the resulting action/status stream, enabling unauthorized browser automation and leakage of page context.
**Insight:** When auditing WebSocket bridges, check whether Origin validation is conditional on the header being present — non-browser clients simply omit it. Also trace session routing: 'first idle connection' pairing lets any peer claim another peer's session.

## Proof of concept (copied exactly from the original report)

**Shell wrapper running the PoC**

```
#!/bin/sh
set -eu

SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"

cd "$SCRIPT_DIR/../.."

exec uv run --no-project \
  --with fastapi \
  --with uvicorn \
  --with websockets \
  python3 "$SCRIPT_DIR/poc.py"
```

