Oct 3, 2026·6 min read·2 visits
Headroom proxy prior to v0.35.0 fails to validate the Origin header during WebSocket handshakes, allowing malicious websites to hijack connections, abuse ambient API credentials, and execute arbitrary commands.
A critical cross-site WebSocket hijacking (CSWSH) vulnerability in headroomlabs-ai/headroom prior to version 0.35.0 allows unauthorized external origins to establish connection channels to the Headroom proxy, enabling arbitrary prompt execution and remote code execution through local tool integration.
The Headroom proxy server, developed by headroomlabs-ai, operates as an intermediary for Large Language Model (LLM) communications. The server compresses request payloads before they reach the upstream LLM providers to reduce processing latency and operational costs. The application exposes an interactive WebSocket endpoint at /v1/responses to facilitate real-time streaming operations between client endpoints and LLM backends.
Prior to version 0.35.0, the WebSocket upgrade handler for the /v1/responses route accepted incoming connection handshakes without performing validation on the HTTP Origin header. Because web browsers do not restrict cross-origin WebSocket connections under the Same-Origin Policy (SOP), any third-party website loaded in a user's browser can initiate a direct connection to a local or internal Headroom proxy on the user's behalf.
This flaw represents a severe weakness matching CWE-1385 (Missing Origin Validation in WebSockets) and CWE-287 (Improper Authentication). If the target proxy runs with ambient authentication credentials—such as the OPENAI_API_KEY stored in server-side environment variables—the incoming hijacked WebSocket session inherits those credentials automatically. This allows unauthorized third-party origins to query upstream models and run local tool suites.
The core technical flaw exists within the WebSocket handshake negotiation implementation. In a standard HTTP application, the browser maintains strict logical boundaries between origins via the Same-Origin Policy (SOP). However, WebSocket connections are explicitly excluded from SOP protections at the browser layer, allowing web scripts to construct connection tunnels to arbitrary targets across different domains.
To compensate for this open transport model, the WebSocket protocol specification requires browsers to append an Origin header to the initial HTTP upgrade handshake request. Target servers are responsible for reading this header and verifying that the requesting origin matches an explicit allowlist. If the server fails to inspect the Origin header during handshake processing, it remains vulnerable to Cross-Site WebSocket Hijacking (CSWSH).
In vulnerable deployments of the Headroom proxy, the FastAPI/ASGI handler accepting connections at /v1/responses accepted the upgrade handshake unconditionally. Once the handshake succeeded, the connection was elevated to a persistent TCP-based WebSocket stream. If the incoming request did not include explicit client authorization tokens, the backend automatically fell back to the administrative server-side OPENAI_API_KEY environment variable, effectively authenticating the hijacked session without client interaction.
The remediation commit c632023cc1ec61d15f8f8e86efe3b54d51604a64 introduces origin verification checks prior to the establishment of the WebSocket session. Below is an analysis of the validation sequence implemented within headroom/proxy/handlers/openai.py to prevent unauthorized cross-origin connections:
def _is_allowed_websocket_origin(headers: dict[str, str]) -> bool:
# Native clients (like curl, CLI tools) commonly omit Origin headers. This absence is allowed.
origin = _header_get(headers, "origin")
if not origin:
return True
allowed_origins = _allowed_ws_origins_from_env()
if allowed_origins is None:
# Fallback to loopback validation if no custom origins are configured
return _is_loopback_ws_origin(origin)
if "*" in allowed_origins:
return True
normalized_origin = _normalize_origin(origin)
if normalized_origin is None:
return False
normalized_allowed = {
normalized
for allowed in allowed_origins
for normalized in (_normalize_origin(allowed),)
if normalized is not None
}
return normalized_origin in normalized_allowedDuring the execution of handle_openai_responses_ws, the server retrieves the headers from the initial handshake. If the origin validation fails, the proxy generates an explicit warning log and closes the websocket session immediately using WebSocket close code 1008 (Policy Violation), halting downstream processing.
if not _is_allowed_websocket_origin(ws_headers):
logger.warning(
"event=websocket_origin_not_allowed request_id=%s session_id=%s path=%s origin=%r",
request_id,
session_id,
_ws_path,
_header_get(ws_headers, "origin"),
)
await websocket.close(code=1008, reason="origin not allowed")
returnExploitation of this vulnerability requires three prerequisites. First, the victim must run the vulnerable Headroom proxy locally or within a reachable private subnet. Second, the proxy must hold active API credentials. Third, the victim must navigate to an attacker-controlled web page.
The attacker-controlled webpage hosts a background JavaScript payload designed to connect to the local Headroom proxy loopback address. When the victim accesses this webpage, the browser executes the script and initiates a connection upgrade request to ws://localhost:8787/v1/responses on the local machine.
Because the browser automatically appends the actual site origin to the connection request, the request headers contain Origin: https://attacker.com. Since the vulnerable proxy lacks verification controls, it completes the handshake. The attacker script can then send formatted JSON commands down the open channel to trigger model operations, exploit local command-execution integrations, or extract sensitive query histories.
The impact of a successful CSWSH exploit on the Headroom proxy is classified as High. Because the proxy processes system commands and connects directly to critical corporate development infrastructure, a hijacked connection bypasses perimeter security protections.
An attacker who establishes a WebSocket channel can issue commands to any connected agent tooling. If the Headroom agent has access to system shells or file-system utilities, the attacker can execute arbitrary commands directly on the host computer running the proxy. This effectively turns a cross-site scripting/phishing vector into an unauthenticated remote code execution exploit.
Additionally, the unauthorized use of LLM credits presents financial and availability concerns. Attackers can execute batch requests to exhaust API quotas or harvest conversation logs containing confidential internal code, proprietary schemas, and access tokens stored in past prompt outputs.
The primary resolution is to upgrade all Headroom proxy installations to version v0.35.0 or higher. This version implements strict Origin header checking and rejects non-loopback connections by default unless an explicit configuration override is provided.
For deployments where immediate upgrading is not possible, administrators should bound the proxy listening socket strictly to the loopback interface (127.0.0.1 or ::1) instead of all interfaces (0.0.0.0). This restricts access from other systems on the network and reduces the attack surface.
If cross-origin access is required, define specific allowed origins using the HEADROOM_WS_ORIGINS or HEADROOM_CORS_ORIGINS environment variables. Avoid using wildcards (*) in production configurations, as wildcards restore the vulnerable state by disabling origin matching logic.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
headroom headroomlabs-ai | < 0.35.0 | v0.35.0 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-1385 (Missing Origin Validation in WebSockets) |
| Attack Vector | Network (Requires User Interaction) |
| CVSS v3.1 Score | 8.8 |
| EPSS Score | 0.00219 (Percentile: 11.24%) |
| Exploit Status | Proof of Concept (PoC) available |
| CISA KEV Status | Not Listed |
The application does not validate the Origin header during the WebSocket handshake, allowing cross-site WebSocket hijacking.
A critical vulnerability exists in the praxis-proxy library where the omission of default limits on HTTP/2 server options allows remote attackers to trigger a Denial of Service (DoS) using an HPACK compression bomb and flow-control window stalls. This vulnerability is cataloged as GHSA-cjcg-cxmh-9wcr.
A Use-After-Free (UAF) vulnerability exists in the sqlite3-ruby native C extension when marshaling arguments for user-defined SQLite aggregate functions with multiple arguments. Due to temporary heap-allocated argument arrays not being registered with the Ruby Garbage Collector, active objects can be prematurely reclaimed, resulting in memory corruption or process-level crashes.
An unauthenticated remote denial of service vulnerability exists in @fastify/busboy versions 3.1.0 through 3.2.0. The vulnerability is caused by an integer wrap-around in the Boyer-Moore-Horspool algorithm implementation inside the sbmh submodule when initializing skip distances. When processing a specific boundary of 252 bytes, the parser triggers an infinite loop, stalling the single-threaded Node.js event loop and exhausting CPU resources.
A critical remote, unauthenticated Denial of Service (DoS) vulnerability in @fastify/busboy (<= 3.2.0) allows attackers to crash the Node.js process. By submitting a crafted multipart/form-data request with a header key matching an inherited property of Object.prototype (like __proto__ or constructor), the internal HeaderParser triggers a synchronous TypeError.
SiYuan is an open-source personal knowledge management system. Its Model Context Protocol (MCP) implementation within the asset.upload tool contains a path-traversal and workspace boundary bypass flaw. This allows remote AI models—acting on behalf of attackers via malicious prompts or documents—to import and read sensitive host-system files, such as private keys and system configurations, through absolute path inputs.
An Server-Side Request Forgery (SSRF) vulnerability via DNS-Rebinding Time-of-Check to Time-of-Use (TOCTOU) has been discovered in SiYuan (思源笔记), an open-source personal knowledge management system. The flaw exists within the AI Agent tools http_request (util.HTTPRequest) and web_fetch (util.WebFetch) of the SiYuan Kernel, allowing unauthenticated remote attackers to bypass SSRF validation and access private internal services or cloud metadata endpoints.