CVE-2026-77776: Headroom LLM proxy: IDOR exposes cross-user memory

CRITICALCISA: TRACK*
Published August 21, 2026
CISO Take

Headroom's LLM proxy trusts a client-supplied x-headroom-user-id header as if it were an authenticated identity, so any caller can name another user's ID and read or write that user's persisted LLM memory with a single unauthenticated HTTP or websocket request. This is a CVSS 9.1 network-exploitable flaw with no privileges or user interaction required, and the reference docker-compose.yml makes it worse by binding 0.0.0.0 with published ports and no required HEADROOM_PROXY_TOKEN — the exact deployment pattern most self-hosted teams copy-paste — turning what should be a locked-down internal service into an open door to every tenant's private conversation history and stored context. There is no public exploit or scanner template yet and it isn't in KEV, but exploitation requires nothing more than sending a forged header, so detection engineering (not exploit-kit maturity) is the real gating factor. Patch to the release containing the resolve_memory_identity fix in headroom/proxy/identity.py, set a required HEADROOM_PROXY_TOKEN, and audit any internet-facing deployment for the insecure default binding before assuming this is theoretical.

Sources:NVDATLASGitHub Advisoryvulncheck.com

What is the risk?

Critical and trivially exploitable: no authentication, no user interaction, low complexity, network vector, and full confidentiality plus integrity impact on stored memory (CVSS 9.1, C:H/I:H/A:N). The exploit is a single forged header value — no chaining, no tooling required — so sophistication is trivial once an attacker can reach the proxy. Real-world exposure is amplified by the vendor's own reference docker-compose configuration, which the server itself warns is insecure at startup (0.0.0.0 binding, published ports, no mandatory proxy token), meaning many self-hosted deployments following the documented quickstart are exposed by default rather than through misconfiguration.

How does the attack unfold?

Discovery
Attacker identifies an internet-exposed Headroom proxy deployed via the vendor's default docker-compose, which binds 0.0.0.0 with published ports and no required proxy token.
AML.T0006
Identity spoofing
Attacker sends a chat completion or websocket request with the x-headroom-user-id header set to a known or guessed victim identifier, which the proxy trusts without binding it to any authenticated caller.
AML.T0091
Data exfiltration
The proxy returns the victim's persisted LLM memory to the attacker, exposing private conversation history and context data.
AML.T0024
Memory poisoning
The attacker writes malicious content into the victim's memory, persisting influence over the victim's future LLM interactions.
AML.T0080.000

What systems are affected?

PackageEcosystemVulnerable RangePatched
headroom-ai——No patch

Do you use headroom-ai? You're affected.

How severe is it?

CVSS 3.1
9.1 / 10
EPSS
0.6%
chance of exploitation in 30 days
Higher than 49% of all CVEs
Exploitation Status
No known exploitation
Sophistication
Trivial

What is the attack surface?

AVACPRUISCIA
AVNetwork
ACLow
PRNone
UINone
SUnchanged
CHigh
IHigh
ANone

What should I do?

1 step
  1. Upgrade to the Headroom release that introduces the resolve_memory_identity seam in headroom/proxy/identity.py, which restricts the x-headroom-user-id header to loopback/allowlisted callers and otherwise binds identity to the proxy-token fingerprint or OS user. Set a required HEADROOM_PROXY_TOKEN in every deployment — do not rely on the pip console script's default 127.0.0.1 binding if you have overridden it. Audit any docker-compose or container deployment for 0.0.0.0 binding with published ports and no token, and place the proxy behind an authenticating reverse proxy or network ACL if it must be internet-reachable. For detection, monitor proxy logs for requests where the x-headroom-user-id header value does not match the expected caller/token/source IP, or for a single source issuing requests with many distinct user-id header values in a short window.

What does CISA's SSVC say?

DecisionTrack*
Exploitationnone
AutomatableYes
Technical Impacttotal

Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Article 15-Accuracy, Robustness and Cybersecurity
ISO 42001
A.6.2.6-Access control for AI system resources and data
NIST AI RMF
GOVERN-1.5-Access control and accountability mechanisms for AI system components
OWASP LLM Top 10
LLM02:2025-Sensitive Information Disclosure

Frequently Asked Questions

What is CVE-2026-77776?

Headroom's LLM proxy trusts a client-supplied x-headroom-user-id header as if it were an authenticated identity, so any caller can name another user's ID and read or write that user's persisted LLM memory with a single unauthenticated HTTP or websocket request. This is a CVSS 9.1 network-exploitable flaw with no privileges or user interaction required, and the reference docker-compose.yml makes it worse by binding 0.0.0.0 with published ports and no required HEADROOM_PROXY_TOKEN — the exact deployment pattern most self-hosted teams copy-paste — turning what should be a locked-down internal service into an open door to every tenant's private conversation history and stored context. There is no public exploit or scanner template yet and it isn't in KEV, but exploitation requires nothing more than sending a forged header, so detection engineering (not exploit-kit maturity) is the real gating factor. Patch to the release containing the resolve_memory_identity fix in headroom/proxy/identity.py, set a required HEADROOM_PROXY_TOKEN, and audit any internet-facing deployment for the insecure default binding before assuming this is theoretical.

Is CVE-2026-77776 actively exploited?

No confirmed active exploitation of CVE-2026-77776 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-77776?

Upgrade to the Headroom release that introduces the resolve_memory_identity seam in headroom/proxy/identity.py, which restricts the x-headroom-user-id header to loopback/allowlisted callers and otherwise binds identity to the proxy-token fingerprint or OS user. Set a required HEADROOM_PROXY_TOKEN in every deployment — do not rely on the pip console script's default 127.0.0.1 binding if you have overridden it. Audit any docker-compose or container deployment for 0.0.0.0 binding with published ports and no token, and place the proxy behind an authenticating reverse proxy or network ACL if it must be internet-reachable. For detection, monitor proxy logs for requests where the x-headroom-user-id header value does not match the expected caller/token/source IP, or for a single source issuing requests with many distinct user-id header values in a short window.

What systems are affected by CVE-2026-77776?

This vulnerability affects the following AI/ML architecture patterns: agent frameworks, LLM proxy/gateway deployments, multi-tenant SaaS LLM applications, memory-augmented conversational AI.

What is the CVSS score for CVE-2026-77776?

CVE-2026-77776 has a CVSS v3.1 base score of 9.1 (CRITICAL). The EPSS exploitation probability is 0.61%.

What is the AI security impact?

Affected AI Architectures

agent frameworksLLM proxy/gateway deploymentsmulti-tenant SaaS LLM applicationsmemory-augmented conversational AI

MITRE ATLAS Techniques

AML.T0024Exfiltration via AI Inference API
AML.T0057LLM Data Leakage
AML.T0080.000Memory

Compliance Controls Affected

EU AI Act: Article 15
ISO 42001: A.6.2.6
NIST AI RMF: GOVERN-1.5
OWASP LLM Top 10: LLM02:2025

What are the technical details?

Original Advisory

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.

Exploitation Scenario

An attacker discovers a Headroom proxy exposed to the internet or a shared network via the vendor's default docker-compose configuration (0.0.0.0 binding, published ports, no required proxy token — the exact setup the server warns about at startup). The attacker sends a chat completion or websocket request carrying an x-headroom-user-id header set to a known or guessed victim identifier (harvested from app usernames, emails, or enumeration). Because the proxy binds memory ownership directly to this unauthenticated header, it returns or updates that victim's stored LLM memory — leaking private conversation history and business context, or allowing the attacker to inject malicious content into the victim's memory that influences the LLM's behavior in future sessions.

Weaknesses (CWE)

CWE-639 — Authorization Bypass Through User-Controlled Key: The system's authorization functionality does not prevent one user from gaining access to another user's data or record by modifying the key value identifying the data.

  • [Architecture and Design] For each and every data access, ensure that the user has sufficient privilege to access the record that is being requested.
  • [Architecture and Design, Implementation] Make sure that the key that is used in the lookup of a specific user's record is not controllable externally by the user or that any tampering can be detected.

Source: MITRE CWE corpus.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

Timeline

Published
August 21, 2026
Last Modified
August 21, 2026
First Seen
August 21, 2026

Related Vulnerabilities