ZeroHour

CVE-2026-77776

niche

User-ID Spoofing (IDOR) in Headroom LLM Proxy Exposes Other Users' LLM Memory

CVSS 4.0
9.3 critical
EPSS
<1%p28
Published
()
Modified
AI analysis

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.

Affected
Headroom (open-source project) Headroom LLM proxy
Estimated exposure
nichelikely on the order of hundreds to a few thousand exposed deployments (estimate) — The disclosure provides no install counts, but pip installs default to loopback (not exposed), so the exposed population is limited to deployments following the shipped docker-compose.yml with 0.0.0.0 and no proxy token, typical of a…

Order-of-magnitude estimate by the model from install counts, market share and public scan data it knows; verify before quoting.

Description

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 news

No ingested article mentions this CVE yet.