# Impact of the nghttp2-nghttpx-upgrade-queue-poison-poc Vulnerability: HTTP/1.1 Upgrade Queue Poisoning Explained

> Learn about the nghttp2-nghttpx-upgrade-queue-poison-poc vulnerability. Discover how attackers exploit HTTP/1.1 Upgrade headers for cross-client response injection and cache contamination.

- Repository: [bikini/exploitarium](https://github.com/bikini/exploitarium)
- Tags: deep-dive
- Published: 2026-09-06

---

**The nghttp2-nghttpx-upgrade-queue-poison-poc vulnerability allows unauthenticated attackers to poison HTTP response queues in nghttpx, causing cross-client response injection, cache contamination, and same-origin content spoofing by smuggling requests through HTTP/1.1 Upgrade headers.**

The nghttp2-nghttpx-upgrade-queue-poison-poc vulnerability targets the reverse-proxy component **nghttpx** within the nghttp2 project. This flaw, demonstrated in the `bikini/exploitarium` repository, exposes a critical HTTP request smuggling vector that enables attackers to inject arbitrary responses destined for other clients sharing persistent backend connections.

## Technical Root Cause in nghttpx

The vulnerability stems from improper handling of HTTP/1.1 Upgrade requests containing a `Content-Length` header. In `nghttpx`, when such a request arrives, the proxy forwards both the request headers and the accompanying body to an HTTP/1.1 backend without stripping the body. If the backend interprets the bytes following the Upgrade header as a new, distinct request—a common behavior in Upgrade-aware servers—the backend places the response into a shared response queue.

## Attack Consequences and Impact

### Cross-Client Response Poisoning

An unauthenticated attacker can craft an Upgrade request with a smuggled request body (e.g., `GET /poisoned`) hidden within the `Content-Length` boundary. When the backend processes this smuggled request and delays its response, that response later gets delivered to a **different** client that happens to reuse the same persistent backend connection.

### Same-Origin Content Injection and Cache Contamination

Because the poisoned response appears to originate from the legitimate target domain, attackers can exploit this for content spoofing or XSS-style attacks. Furthermore, intermediate caches trusting `nghttpx` response boundaries may store the attacker-controlled payload, leading to widespread cache poisoning and further distribution of malicious content.

### Denial of Service

The attacker can disrupt normal application routing by forcing unexpected responses to victim requests, effectively breaking the intended request-response mapping and causing service degradation.

## Proof-of-Concept Implementation

The `bikini/exploitarium` repository provides a complete proof-of-concept in [`poc.py`](https://github.com/bikini/exploitarium/blob/main/poc.py) that orchestrates the attack against vulnerable nghttpx versions (notably v1.69.0). The demonstration uses a lightweight backend server that mimics Upgrade-aware behavior to validate the queue-poisoning exploit.

The attack flow executed by the PoC:

1. The attacker sends `GET /upgrade` with `Upgrade: websocket` and a `Content-Length` header enclosing a smuggled request (`GET /poisoned`).
2. The backend replies `UPGRADE-REJECT` to the Upgrade request, then parses the smuggled request and delays its response.
3. The attacker's connection closes, and a subsequent victim request (`GET /victim`) reuses the same backend connection.
4. The delayed `/poisoned` response is delivered to the victim, displaying `SMUGGLED-BENIGN-PAYLOAD` instead of the legitimate `VICTIM-RESPONSE`.

To reproduce the vulnerability locally:

```bash

# Build a vulnerable nghttpx binary (v1.69.0) and run the PoC

python3 poc.py --nghttpx ./build/src/nghttpx --cwd ./nghttp2-v1.69.0

```

For detailed protocol tracing:

```bash

# Run with verbose protocol traces

python3 poc.py --nghttpx ./build/src/nghttpx --cwd ./nghttp2-v1.69.0 --verbose

```

To verify the fix:

```bash

# Run against a fixed (upstream-master) binary to confirm mitigation

python3 poc.py --nghttpx ./build-fixed/src/nghttpx --cwd ./nghttp2-fixed --expect-fixed

```

Key files in the repository:

- [`README.md`](https://github.com/bikini/exploitarium/blob/main/README.md) – Contains the architectural overview, impact analysis, and reproduction steps.
- [`poc.py`](https://github.com/bikini/exploitarium/blob/main/poc.py) – Implements the backend server, launches `nghttpx`, and validates queue-poisoning behavior.
- [`evidence/local-verification.txt`](https://github.com/bikini/exploitarium/blob/main/evidence/local-verification.txt) – Provides transcripts confirming vulnerable versus fixed behavior.

## Upstream Mitigation

The upstream fix (commit `ab28105c…`) introduces strict validation in nghttpx that rejects Upgrade or CONNECT requests containing `Transfer-Encoding` or `Content-Length` headers. This prevents the body from being forwarded to the backend, thereby eliminating the queue-poisoning attack vector entirely.

## Summary

- The nghttp2-nghttpx-upgrade-queue-poison-poc vulnerability enables HTTP request smuggling through HTTP/1.1 Upgrade headers with `Content-Length` bodies.
- Attackers can inject responses into other clients' connections, enabling cross-client poisoning, cache contamination, and same-origin attacks.
- The vulnerability affects nghttpx versions prior to the fix in commit `ab28105c…`, including v1.69.0.
- The `bikini/exploitarium` repository provides [`poc.py`](https://github.com/bikini/exploitarium/blob/main/poc.py) to demonstrate the exploit and verify fixes.
- Upstream mitigation rejects Upgrade/CONNECT requests with body indicators, preventing request smuggling.

## Frequently Asked Questions

### What versions of nghttp2 are affected by this vulnerability?

The vulnerability affects nghttpx versions prior to the upstream fix in commit `ab28105c…`, specifically including v1.69.0 as confirmed by the proof-of-concept in the `bikini/exploitarium` repository. Any deployment forwarding HTTP/1.1 Upgrade requests with `Content-Length` headers to backends is vulnerable.

### How does the nghttpx upgrade queue poisoning attack work?

The attack works by sending an HTTP/1.1 Upgrade request with a `Content-Length` header containing a smuggled request body. Nghttpx forwards this body to the backend, which interprets it as a new request. The backend queues the response, which is later served to a different client reusing the same persistent connection, resulting in response poisoning.

### Is there a workaround without upgrading nghttp2?

The only reliable mitigation is to apply the upstream fix or ensure nghttpx rejects Upgrade and CONNECT requests that include `Content-Length` or `Transfer-Encoding` headers. Blocking such requests at a preceding load balancer or WAF may provide temporary protection, but upgrading remains the recommended solution.

### Where can I find the proof-of-concept code for this vulnerability?

The complete proof-of-concept is available in the `bikini/exploitarium` repository under the `nghttp2-nghttpx-upgrade-queue-poison-poc` directory. The [`poc.py`](https://github.com/bikini/exploitarium/blob/main/poc.py) file contains the implementation, while [`README.md`](https://github.com/bikini/exploitarium/blob/main/README.md) provides detailed documentation and [`evidence/local-verification.txt`](https://github.com/bikini/exploitarium/blob/main/evidence/local-verification.txt) contains verification transcripts.