Vega VEGA / Bug List / CVE-2026-42530
Finding · Nginx · ngx_http_v3_module · HTTP/3 QUIC
CVE-2026-42530

HTTP/3 QPACK encoder stream reopen triggers a use-after-free in the NGINX worker

ngx_http_v3_module · QPACK encoder stream
Affects NGINX OSS 1.31.0–1.31.1 HTTP/3 (QUIC) ngx_http_v3_module Data plane only
Disclosure timeline
  1. Reported
  2. Confirmed
  3. Patched (1.31.2)
  4. Published

Summary

CVE-2026-42530 is a use-after-free in NGINX Open Source’s HTTP/3 stack (ngx_http_v3_module). When NGINX is configured to serve HTTP/3 over QUIC, a remote, unauthenticated client can craft an HTTP/3 session that reopens a QPACK encoder stream. NGINX does not expect that stream to be reopened, and the resulting object lifetime confusion lets a freed structure be referenced again inside the worker process.

In the common case the bug crashes the affected NGINX worker, which the master process then restarts — a remote denial-of-service against the data plane. On builds where Address Space Layout Randomization (ASLR) is disabled, or where an attacker can otherwise bypass ASLR, the use-after-free can be steered toward remote code execution in the worker context.

This is strictly a data plane issue: there is no control plane exposure.

Impact & exploitability

The attacker model is the strongest one a network service can have — a remote, unauthenticated peer that merely needs to speak HTTP/3 to a vulnerable listener:

  • Attacker model: remote, unauthenticated client over HTTP/3 / QUIC
  • Precondition: NGINX built and configured with HTTP/3 enabled (a listen directive carrying quic)
  • Primitive: use-after-free in the QPACK encoder-stream handling path
  • Baseline impact: worker crash and restart → remote denial of service
  • Escalated impact: code execution in the worker process when ASLR is disabled or bypassed

F5, the assigning CNA, rates the issue Critical / 9.2 (CVSS v4.0) and High / 8.1 (CVSS v3.1). The “conditions beyond their control” qualifier in the advisory — and the ASLR caveat on RCE — is exactly why the v3.1 and v4.0 scores diverge: a reliable crash is straightforward, but turning it into code execution depends on the target’s memory-layout hardening.

Root cause

HTTP/3 carries its header compression state on dedicated QPACK control streams. Each direction negotiates a single QPACK encoder stream and a single QPACK decoder stream, established once per connection. The protocol treats these as long-lived, singleton unidirectional streams — they are opened once and are not meant to be re-established within the same session.

The vulnerability is a lifetime-management gap: the HTTP/3 module does not robustly reject a peer that opens a second QPACK encoder stream after one already exists for the connection. Reopening the encoder stream tears down or reinitializes state associated with the first stream while a reference to the already-released object is still reachable from the connection’s HTTP/3 context. A subsequent operation on that dangling reference is the use-after-free.

Conceptually, the unsafe shape is “trust that a per-connection singleton stream is created exactly once,” without a guard that fails the connection when the peer violates that assumption:

peer opens QPACK encoder stream ──▶ v3 module allocates encoder state (A)
peer opens QPACK encoder stream ──▶ module re-handles "new" encoder stream,
releasing/replacing state (A)
later frame references the old ──▶ use-after-free on freed object (A)
encoder-stream object

The fix tightens this path so that an attempt to reopen an already-established QPACK encoder stream is treated as a connection error rather than silently re-running first-time setup against live state.

QPACK encoder/decoder streams are per-connection control channels. Allowing a second one to be “opened” is not a benign duplicate — it re-enters initialization logic that assumes a clean slate, which is what frees the object the connection still points at.

Reproducer

Not yet available

Nebula Security will release the PoC around 1 month after the disclosure.

Exploit

Not yet available

Nebula Security will release the exploit around 1 month after the disclosure.

Patch

The issue is fixed in NGINX Open Source 1.31.2. The affected window is the 1.x mainline range 1.31.0 – 1.31.1, all of which ship the vulnerable ngx_http_v3_module behavior.

Upgrading to 1.31.2 (or later) is the complete remedy. Products that bundle NGINX Open Source inherit the same exposure through their base components; per F5’s advisory the following were evaluated as carrying the vulnerable code with no fix candidate of their own at publication time:

  • NGINX Instance Manager 2.17.0 – 2.22.0
  • NGINX Gateway Fabric 2.0.0 – 2.6.3 and 1.3.0 – 1.6.2
  • NGINX Ingress Controller 5.0.0 – 5.5.0, 4.0.0 – 4.0.1, and 3.5.0 – 3.7.2

For those, the practical fix is to move to a build that incorporates NGINX OSS 1.31.2+, or apply the HTTP/3 mitigation below in the interim.

Mitigation

If you cannot immediately upgrade to NGINX OSS 1.31.2, disable HTTP/3:

# Remove `quic` from every listen directive so the HTTP/3 path is not reachable.
# Before (vulnerable surface exposed):
listen 443 quic reuseport;
listen 443 ssl;
# After (HTTP/3 disabled; HTTP/2 + HTTP/1.1 over TLS still served):
listen 443 ssl;

Because the bug lives entirely in the HTTP/3 / QUIC code path, removing quic from all listen directives closes the attack surface completely. Servers that were never built with HTTP/3, or that do not enable it, are not exposed.

There is no control plane component to this vulnerability and no need to rotate credentials or certificates; the only actions required are patching or disabling HTTP/3.

Timeline & credit

The issue was reported to F5/NGINX under coordinated disclosure, confirmed, fixed in NGINX Open Source 1.31.2, and published as CVE-2026-42530 (F5 ID NPS-8), classified as CWE-416: Use After Free.

This vulnerability was autonomously discovered by VEGA agent.

Related findings

See all ↗
Vega · AI security research

Find bugs in your code. Before anyone else does.

Sign up