CVE-2026-77775: Headroom: SSRF via client-set upstream base URL

HIGH
Published August 21, 2026
CISO Take

Headroom's LLM proxy lets any client dictate the upstream host it talks to via the x-headroom-base-url header, and the code only checks that the value parses as a URL with a hostname — it never blocks loopback, RFC 1918, or cloud metadata addresses. Because the component is a proxy, the response from whatever host the attacker names comes straight back to them, and the Authorization header riding along on the request is forwarded unchanged to that attacker-controlled destination, so this is both an internal-network SSRF and a credential-theft primitive in one request. There's no EPSS score, no known public exploit, and it isn't in CISA KEV yet, but the attack needs no authentication and no user interaction (CVSS 8.6, AV:N/AC:L/PR:N/UI:N), and the project's own reference docker-compose.yml binds 0.0.0.0 with published ports and no HEADROOM_PROXY_TOKEN set — the exact insecure default the server warns about at its own startup — so teams that deployed via the documented quickstart are plausibly exposed right now. Patch to the version that ships upstream_guard.py (present from v0.36.1), or in the interim set HEADROOM_PROXY_TOKEN, bind to 127.0.0.1 instead of 0.0.0.0, and add egress/network-policy rules blocking the proxy host from reaching 169.254.169.254 and RFC 1918 ranges; alert on any x-headroom-base-url value outside an explicit allowlist of approved upstreams.

Sources:NVDGitHub AdvisoryATLASvulncheck.com

What is the risk?

High confidence, low-effort exploit: the flaw requires only a crafted HTTP header, no auth, no user interaction, and no special tooling (CWE-918, CVSS 8.6). Exploitability is amplified by the shipped reference deployment (docker-compose with --host 0.0.0.0, published ports, and no proxy token by default), which the server itself warns is insecure at startup — meaning many real deployments likely inherited the vulnerable default rather than a hardened config. There's no evidence of active exploitation (not in CISA KEV, no EPSS score, no public PoC or Nuclei template), so this should be treated as a high-priority patch item rather than an active-incident item. Impact is severe where exploited: confidentiality is fully compromised (C:H) because the proxy discloses internal service responses and forwards live credentials (the Authorization header) to an attacker-chosen host, with no integrity or availability impact.

How does the attack unfold?

Discovery
Attacker scans for internet-exposed Headroom proxy instances deployed with the insecure default docker-compose (0.0.0.0 bind, no proxy token).
AML.T0006
Exploitation
Attacker sends a proxied request with x-headroom-base-url pointing at an internal service or cloud metadata address; the proxy accepts it with no address validation.
AML.T0049
Credential theft
The proxy forwards the Authorization header unchanged to the attacker-designated host and returns the response, disclosing internal data or cloud IAM credentials.
AML.T0055
Impact
Attacker uses the stolen credentials or disclosed internal data for lateral movement, further exfiltration, or compromise of the victim's cloud environment.

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
8.6 / 10
EPSS
0.6%
chance of exploitation in 30 days
Higher than 48% of all CVEs
Exploitation Status
No known exploitation
Sophistication
Trivial

What is the attack surface?

AVACPRUISCIA
AVNetwork
ACLow
PRNone
UINone
SChanged
CHigh
INone
ANone

What should I do?

1 step
  1. 1) Upgrade Headroom to the version containing headroom/proxy/upstream_guard.py (confirmed present at v0.36.1) which validates upstream destinations. 2) If upgrading isn't immediate, set HEADROOM_PROXY_TOKEN so passthrough/proxy routes require authentication, and stop binding --host 0.0.0.0 in docker-compose.yml — bind to 127.0.0.1 or a private interface and remove published ports from public networks. 3) Add network-layer egress controls on the proxy host blocking outbound access to 169.254.169.254 (and equivalent GCP/Azure metadata IPs) and RFC 1918/loopback ranges unless explicitly required. 4) Implement an allowlist of approved upstream hosts for x-headroom-base-url rather than accepting arbitrary client-supplied values. 5) Detection: alert on proxy logs where x-headroom-base-url resolves to a private/link-local/metadata IP, and monitor for anomalous outbound connections from the proxy host to non-LLM-provider destinations.

What does CISA's SSVC say?

DecisionTrack
Exploitationnone
AutomatableYes
Technical Impactpartial

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

How is it classified?

Data LeakageAuth BypassPrivacy ViolationAPIInferenceAML.T0049AML.T0055

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Article 15-Accuracy, robustness and cybersecurity
ISO 42001
A.8.3-Operational security for AI systems
OWASP LLM Top 10
LLM02-Sensitive Information Disclosure

Frequently Asked Questions

What is CVE-2026-77775?

Headroom's LLM proxy lets any client dictate the upstream host it talks to via the x-headroom-base-url header, and the code only checks that the value parses as a URL with a hostname — it never blocks loopback, RFC 1918, or cloud metadata addresses. Because the component is a proxy, the response from whatever host the attacker names comes straight back to them, and the Authorization header riding along on the request is forwarded unchanged to that attacker-controlled destination, so this is both an internal-network SSRF and a credential-theft primitive in one request. There's no EPSS score, no known public exploit, and it isn't in CISA KEV yet, but the attack needs no authentication and no user interaction (CVSS 8.6, AV:N/AC:L/PR:N/UI:N), and the project's own reference docker-compose.yml binds 0.0.0.0 with published ports and no HEADROOM_PROXY_TOKEN set — the exact insecure default the server warns about at its own startup — so teams that deployed via the documented quickstart are plausibly exposed right now. Patch to the version that ships upstream_guard.py (present from v0.36.1), or in the interim set HEADROOM_PROXY_TOKEN, bind to 127.0.0.1 instead of 0.0.0.0, and add egress/network-policy rules blocking the proxy host from reaching 169.254.169.254 and RFC 1918 ranges; alert on any x-headroom-base-url value outside an explicit allowlist of approved upstreams.

Is CVE-2026-77775 actively exploited?

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

How to fix CVE-2026-77775?

1) Upgrade Headroom to the version containing headroom/proxy/upstream_guard.py (confirmed present at v0.36.1) which validates upstream destinations. 2) If upgrading isn't immediate, set HEADROOM_PROXY_TOKEN so passthrough/proxy routes require authentication, and stop binding --host 0.0.0.0 in docker-compose.yml — bind to 127.0.0.1 or a private interface and remove published ports from public networks. 3) Add network-layer egress controls on the proxy host blocking outbound access to 169.254.169.254 (and equivalent GCP/Azure metadata IPs) and RFC 1918/loopback ranges unless explicitly required. 4) Implement an allowlist of approved upstream hosts for x-headroom-base-url rather than accepting arbitrary client-supplied values. 5) Detection: alert on proxy logs where x-headroom-base-url resolves to a private/link-local/metadata IP, and monitor for anomalous outbound connections from the proxy host to non-LLM-provider destinations.

What systems are affected by CVE-2026-77775?

This vulnerability affects the following AI/ML architecture patterns: LLM gateways/proxies, model serving, agent frameworks, API gateways.

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

CVE-2026-77775 has a CVSS v3.1 base score of 8.6 (HIGH). The EPSS exploitation probability is 0.59%.

What is the AI security impact?

Affected AI Architectures

LLM gateways/proxiesmodel servingagent frameworksAPI gateways

MITRE ATLAS Techniques

AML.T0049Exploit Public-Facing Application
AML.T0055Unsecured Credentials

Compliance Controls Affected

EU AI Act: Article 15
ISO 42001: A.8.3
OWASP LLM Top 10: LLM02

What are the technical details?

Original Advisory

Headroom's LLM proxy lets a client choose the upstream destination with the x-headroom-base-url request header. _resolve_openai_upstream_base in headroom/proxy/handlers/openai.py accepts the header value, requires only that it parse with an http or https scheme and a hostname, and returns it for use as the upstream base; _select_passthrough_base_url in headroom/providers/proxy_routes.py reads the same header for the passthrough routes. No check rejects loopback, link-local, or RFC 1918 destinations, and because the component is a proxy the upstream response is returned to the caller, so the request reaches internal services and cloud metadata addresses and their responses are disclosed. The Authorization header accompanying the request is forwarded unchanged to the caller-designated host. 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 instance exposed on the internet (a likely outcome given the insecure docker-compose default). They send a normal-looking chat completion request but set the header x-headroom-base-url: http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>. The proxy's _resolve_openai_upstream_base function accepts this as a valid http URL with a hostname, forwards the request — including the Authorization header meant for the legitimate LLM provider — to the cloud metadata service, and returns the response (temporary IAM credentials) directly to the attacker. The attacker now has valid cloud credentials scoped to the host's role, which they can use for lateral movement, data exfiltration from cloud storage, or further compromise of the victim's cloud environment — all without ever needing valid Headroom credentials.

Weaknesses (CWE)

CWE-918 — Server-Side Request Forgery (SSRF): The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.

Source: MITRE CWE corpus.

CVSS Vector

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

Timeline

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

Related Vulnerabilities