Skip to content
RESEARCH INDEX BREACHROAD / INTELLIGENCE NOTE

Headroom LLM Proxy: A Header Selects Another User's Memory and Private Upstreams

CVE-2026-77775 and 77776 expose reflected SSRF with Authorization forwarding and cross-user LLM memory access in network-reachable deployments.

PUBLIC RESEARCH
AUTHOR
/ CEO Breachroad · OSCP · PNPT
PUBLISHED
21 August 2026
READING TIME
19 min read
TOPIC
AI Security
Headroom LLM Proxy: A Header Selects Another User's Memory and Private Upstreams

Two CVEs were published for Headroom, an LLM proxy and optimisation layer, on 21 August. CVE-2026-77776 lets a client supply x-headroom-user-id and read or change another user’s stored memory. CVE-2026-77775 lets x-headroom-base-url choose an HTTP or HTTPS upstream, including loopback, RFC 1918, link-local and metadata destinations. The response is returned to the caller, and the request’s Authorization header can be forwarded to the selected host.

Risk increases because local CLI and reference deployment defaults diverged. The pip entry point binds to 127.0.0.1, while the supplied docker-compose.yml published ports on 0.0.0.0 without requiring HEADROOM_PROXY_TOKEN. The server warned at startup, but the example made a network-reachable, unauthenticated data plane easy to create.

CVE-2026-77776: an identifier is not an identity

Chat-completion and WebSocket handlers read x-headroom-user-id without binding it to the caller. A client could name another person’s identifier and reach that memory partition. The CVSS 4.0 score is 9.3: network attack, low complexity, no account and high confidentiality and integrity impact.

This is a multi-tenancy failure. A header can carry identity from a trusted gateway only when the proxy strips client copies, the gateway authenticates the user, the value is signed or set out of band, and trusted sources are unambiguous. Otherwise it is user input, not evidence.

The fix introduces one resolve_memory_identity() seam. For remote callers, memory is tied to the proxy-token fingerprint or operating-system user; the header is honoured only through loopback or an approved resolution path. One central decision is safer than six duplicated header reads.

CVE-2026-77775: reflected SSRF with credential forwarding

Functions selecting an OpenAI upstream accepted x-headroom-base-url, checked only for an HTTP or HTTPS scheme and hostname, and sent the request. They did not reject loopback, link-local or private ranges. Because Headroom is a proxy, the upstream response returned to the caller. That is stronger than blind SSRF because the attacker can inspect results.

The Authorization header was also forwarded unchanged to the client-selected host. A user’s LLM provider token could therefore be redirected to an attacker-operated server. In cloud environments the destination might be a metadata endpoint; in a cluster it might be an internal panel or API reachable only from the proxy network.

The fix adds upstream_guard.is_safe_upstream_url() at every base-URL entry point, blocking metadata, RFC 1918, loopback and link-local destinations. Private model providers require an explicit HEADROOM_ALLOWED_BASE_URLS policy. Validation must also apply after DNS resolution and to every redirect, because a textual hostname check alone is vulnerable to rebinding or destination changes.

Seven fixes, not only two CVEs

Security merge #2207 addresses seven findings. Besides SSRF and memory identity, it pins SHA-256 for five downloaded tool binaries, restricts telemetry import and 15 operational GET endpoints to loopback, hardens Compose, removes default Neo4j passwords and applies filter="data" to tar extraction.

The issues interact. An unauthenticated public bind turned local weaknesses into remote ones. Unverified binaries created supply-chain exposure. Broad operational endpoints revealed state. Assessing only two CVE numbers can miss configuration that still leaves unnecessary attack surface.

Assessing a deployment

Identify the image version, commit or release containing #2207. Do not assume a mutable latest tag contains the fix; record the digest. Inspect effective Compose configuration, bind address, published ports, reverse proxy and HEADROOM_PROXY_TOKEN. Determine reachability from the Internet, corporate network, other Kubernetes namespaces and local shared processes.

Check whether clients send x-headroom-user-id or x-headroom-base-url, who sets each value, and whether ingress removes user-supplied copies. Map memory storage, retention and tenant identifiers. For upstreams, record allowed providers, DNS, ports and egress proxy. A private RFC 1918 LLM needs a precise exception, not complete SSRF-control disablement.

Secure update and configuration

Deploy a release containing #2207 or a later maintainer-confirmed build. Require a strong HEADROOM_PROXY_TOKEN, bind to loopback or a private interface and use an authenticated reverse proxy. Do not publish Neo4j or operational endpoints. Restrict egress to approved LLM origins, including scheme, hostname and port.

In multi-user environments, never use an arbitrary header as identity. The gateway authenticates a client and passes a non-spoofable principal; Headroom uses a custom resolver. Apply the same identity to read, write, WebSocket, retry and tool paths.

Regression tests should prove a remote client cannot select another user, a private address, loopback, link-local, metadata or a different port on an allowed hostname. Cover redirects and DNS answers that change between validation and connection. Do not probe a real metadata service in production; use controlled destinations in an isolated environment.

Hunting and exposure response

Search access logs for x-headroom-base-url values containing unusual domains, literal IPs, ports or schemes, and responses resembling internal services. Review outbound DNS and HTTP proxy traffic from Headroom. If Authorization reached an untrusted host, rotate the specific provider token and investigate its use.

For memory, look for one source cycling through many x-headroom-user-id values, operations across unrelated tenants and changes without a corresponding authenticated session. Determine whether memory contained prompts, document excerpts, agent decisions or personal data. It is not necessarily “just cache”; poisoned memory can shape future output and actions.

Patching does not reverse disclosure. Preserve logs, storage snapshots and configuration before removing foreign entries. If memory may have been poisoned, validate or rebuild it from a trusted source rather than only changing a token.

Useful telemetry without another leak

Logging complete headers makes hunting easy but can expose Authorization, user identifiers and prompt content. Record the target origin, policy decision, a principal hash, status and latency while always redacting tokens. Proxy logs should have tighter access than normal developer output.

For memory operations, retain read and write events with tenant, resolver version and an immutable request ID. Audit records do not need full documents, but they must show who crossed a boundary. That design accelerates CVE investigation without creating a second sensitive data store.

Project facts and Breachroad conclusions

CVE mechanisms, CLI binding, risky Compose defaults, #2207 scope and new variables come from public records and the Headroom repository. The sources do not report active exploitation. Confirm a safe release in project changelogs because the CVE describes code and a merge rather than every distribution channel.

Gateway identity, complete origin validation, hunting and memory recovery are Breachroad conclusions. AI security training teaches these boundaries, and an AI security assessment can examine proxy configuration, tenancy, memory, tokens and egress.

Sources

SHARE / COPY