CVE-2026-71416: Headroom WebSocket proxy spends your OpenAI key for any reachable browser

CVE-2026-71416: Headroom WebSocket proxy spends your OpenAI key for any reachable browser

How to fix CVE-2026-71416: upgrade headroom-ai to 0.35.0

3 min read605 words
Contents

If a browser on your network can open ws://your-host:8787/v1/responses, it can ride Headroom's stored OpenAI key. Before headroom-ai 0.35.0, the Responses WebSocket handler accepted the upgrade without checking Origin, then injected Authorization: Bearer $OPENAI_API_KEY when the client sent none. A malicious page (or headless browser) that can reach that listener spends your quota, drives arbitrary prompts and tools, and can reach RCE if the upstream session exposes a shell tool. CVE-2026-71416 is the Sept 11 ID for a fix that already shipped in 0.35.0 on Aug 13.

Upgrade to headroom-ai>=0.35.0 (current line is 0.37.0). If you must stay on an older build, do not bind the proxy where browsers can reach it, and do not keep OPENAI_API_KEY in the proxy process environment.

What breaks

GitHub advisory GHSA-h46j-26q3-rggf / CVE-2026-71416 rates this High (CVSS 8.8, AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H). User interaction is required in the CVSS sense (a browser must run the malicious WebSocket client), but no Headroom login is required once the page can reach the proxy. The GHSA PoC targets ws://<host>:8787/v1/responses with a response.create payload, including a local shell tool.

The advisory explains the missing check and the env-var auth fallback. The Aug 13 0.35.0 patch does three things the GHSA does not spell out. It rejects disallowed origins with WebSocket close code 1008 and reason origin not allowed, logging event=websocket_origin_not_allowed. Native clients that omit Origin still pass. When Origin is present and you have not configured an allowlist, only loopback origins are accepted. Operators set the allowlist with HEADROOM_WS_ORIGINS (comma-separated); if that is empty, Headroom also reads HEADROOM_CORS_ORIGINS. A literal * in the list re-opens every origin.

PyPI package name is headroom-ai (not the unrelated headroom package). GitHub shows about 71k stars; PyPI recent downloads for headroom-ai are on the order of hundreds of thousands per month. Affected: headroom-ai < 0.35.0 (GHSA marks the vulnerable train from 0.23.0). Fixed: 0.35.0 and later.

Who is not in scope

  • Installs already on headroom-ai>=0.35.0 (0.35.0 hit PyPI 2026-08-13; 0.37.0 is current).
  • Library-only or MCP-only usage that never runs the local OpenAI Responses WebSocket proxy on /v1/responses.
  • Proxies that never store OPENAI_API_KEY in the process environment and require the client to send its own Authorization header (the GHSA exploit path relies on the env-var injection).
  • Listeners that browsers cannot reach (true localhost-only bind with no malicious local content, or network policy that blocks the WS port).

How to check

From the environment that runs the proxy:

pip show headroom-ai

Any printed version below 0.35.0 is vulnerable. Also confirm whether the proxy process exports OPENAI_API_KEY and whether anything listens on port 8787 (or your configured proxy port) beyond loopback. After upgrade, if browsers on other origins must use the WS endpoint, set an explicit allowlist rather than relying on the loopback default:

export HEADROOM_WS_ORIGINS=https://app.example.com,http://127.0.0.1:3000

How to fix

Upgrade headroom-ai to the patched release or newer.

pip install 'headroom-ai>=0.35.0'

Restart the proxy. Prefer not to put long-lived provider keys in the proxy environment if clients can supply their own auth. Do not set HEADROOM_WS_ORIGINS=* unless you fully trust every browser that can reach the listener.

What this is not

This is not a bug in OpenAI, and it is not unauthenticated RCE inside the Headroom process itself. Damage is CSWSH against the proxy: a reachable WebSocket plus a stored provider key. RCE appears only when the proxied session can invoke dangerous tools (for example a local shell tool). CVE assignment landed about a month after 0.35.0 shipped; the upgrade urgency is for fleets still below that floor.

References

Continue reading

All posts