CVE-2026-77776: Headroom Proxy Treats the Client-Supplied x-headroom-user-id Header as an Authenticated Identity
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 resolvememoryidentity 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 HEADROOMPROXYTOKEN, 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.
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
In the deployment, provide HEADROOM_PROXY_TOKEN instead of relying on a compose file that ships without a required token; ensure the server is not started/configured without the token so the data-plane routes are authenticated.
Headroom Proxy (docker-compose deployment) HEADROOM_PROXY_TOKEN = required (set a non-empty value) - Configuration
Apply the fix that adds resolve_memory_identity in headroom/proxy/identity.py to honor x-headroom-user-id only when the caller is loopback or allowlisted; for all other callers, bind the memory identity to the proxy-token fingerprint or the operating system user instead of trusting the header.
Headroom Proxy (identity handling) x-headroom-user-id usage = honor only for loopback or allowlisted callers; otherwise ignore - Compensating control
Limit network access to the Headroom Proxy data-plane routes (e.g., published ports) so only loopback/allowlisted callers can reach them; avoid exposing the routes broadly when HEADROOM_PROXY_TOKEN is not configured.
Event History
Frequently Asked Questions
Which deployments are most exposed?
Deployments that expose the proxy to the network without requiring HEADROOM_PROXY_TOKEN are most exposed. The reference docker-compose.yml publishes ports and uses --host 0.0.0.0, whereas the pip console script binds to 127.0.0.1 by default.
What does an attacker need to exploit this issue?
An attacker needs network access to affected proxy data-plane routes and the ability to send requests with a chosen x-headroom-user-id header. No authentication or user interaction is required in the described unauthenticated network-exposed deployment.
What can an attacker access or change?
An attacker can supply another user's identifier as x-headroom-user-id and read or write that user's stored LLM memory. The affected handling includes chat-completion and websocket paths.
What can be done before applying the fix?
Restrict proxy access to loopback or trusted, allowlisted callers, and require HEADROOM_PROXY_TOKEN for network-accessible deployments. Do not expose the proxy's published ports to untrusted networks while unauthenticated.