CVE-2026-77776
nicheUser-ID Spoofing (IDOR) in Headroom LLM Proxy Exposes Other Users' LLM Memory
Headroom's LLM proxy determines which user's stored LLM memory to serve from the client-supplied x-headroom-user-id request header, reading it directly on the chat completion and websocket paths without binding the value to the actual caller (CWE-639, authorization bypass via user-controlled key). Any client that can reach the proxy can therefore send another user's identifier in that header and read or write that user's stored LLM memory. The pip console script binds to 127.0.0.1 by default, but deployments following the shipped docker-compose.yml run with --host 0.0.0.0, published ports, and no required HEADROOM_PROXY_TOKEN — a configuration the server itself warns about at startup — leaving the affected data-plane routes open to the network without authentication. The flaw affects confidentiality and integrity of stored user memory (CVSS 4.0 scores it 9.3 critical); no host-level or system-level impact is described. There is no public proof-of-concept, no CISA KEV listing, and EPSS is low at 0.3%, indicating no known exploitation to date.
What to do: Upgrade to the Headroom release containing the fix (the version adding the resolve_memory_identity seam in headroom/proxy/identity.py; no fixed version number was published in the disclosure data). If you run the shipped docker-compose.yml, set HEADROOM_PROXY_TOKEN or restrict network access to the published ports, since that configuration is unauthenticated and network-exposed. Audit whether your deployment binds 0.0.0.0 and whether external callers can set x-headroom-user-id, and until patching rely on loopback binding or allowlisting to limit exposure.
| Headroom (open-source project) Headroom LLM proxy | — |
Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.
Headroom's LLM proxy derives the memory owner from the x-headroom-user-id request header. The header is read directly at several points in headroom/proxy/handlers/openai.py, including the chat completion and websocket paths, and nothing binds the value to the caller. A client can therefore name another user's identifier and read or write that user's stored LLM memory. The fix introduces a single resolve_memory_identity seam in headroom/proxy/identity.py that honors the header only for loopback or allowlisted callers and otherwise binds the identity to the proxy-token fingerprint or the operating system user. The pip console script binds 127.0.0.1 by default, but the reference docker-compose.yml ships --host 0.0.0.0 with published ports and no required HEADROOM_PROXY_TOKEN, which the server itself warns about at startup, so a deployment following the shipped compose exposes the affected data-plane routes to the network without authentication.
- Weakness
- CWE-639
- Vector
- CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
In the news0 stories
No ingested article mentions this CVE yet.