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

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 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:


# 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:


# Run with verbose protocol traces

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

To verify the fix:


# 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 – Contains the architectural overview, impact analysis, and reproduction steps.
  • poc.py – Implements the backend server, launches nghttpx, and validates queue-poisoning behavior.
  • 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 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 file contains the implementation, while README.md provides detailed documentation and evidence/local-verification.txt contains verification transcripts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →