← Back to Feed CACHED · 2026-10-07 04:58:14 · CACHE_KEY CVE-2026-42530
CVE-2026-42530 · CWE-416 · Disclosed 2026-06-17

NGINX Open Source ngx_http_v3_module QPACK Encoder Stream Use-After-Free

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

Like leaving a loaded mousetrap in a locked room that only certain guests have the key to

CVE-2026-42530 is a use-after-free in NGINX Open Source's ngx_http_v3_module, affecting only mainline versions 1.31.0 and 1.31.1 (fixed in 1.31.2, released 2026-06-17). The bug lives in HTTP/3's QPACK header-compression logic: a session-scoped pointer retains a reference to memory allocated from a unidirectional encoder stream's pool. When that stream closes, the pool is freed, but the session keeps a dangling pointer. A second encoder stream on the same connection then writes into freed heap, crashing the worker. CyStack researcher Trung Nguyen characterized the root cause as a "lifetime mismatch" between the connection-level session and the transient stream. The flaw also impacts NGINX Gateway Fabric 2.0.0–2.6.3, NGINX Ingress Controller 3.5.0–3.7.2 / 4.0.0–4.0.1 / 5.0.0–5.5.0, and NGINX Instance Manager 2.17.0–2.22.0.

F5's vendor rating of HIGH / 8.1 (CVSS v3.1) is honest — the AC:H reflects that code execution requires ASLR to be disabled or bypassed, which is uncommon on modern Linux. The CVSS v4.0 bump to 9.2 over-indexes on the theoretical RCE ceiling and under-weights the narrow deployment preconditions: the server must be on mainline 1.31.x, compiled with --with-http_v3_module, configured with listen … quic and http3 on, and reachable over UDP 443. Reliable DoS (worker restart via crash) requires none of the ASLR gymnastics and is the more realistic impact. The vendor score is directionally right; we shave it to 7.5 to reflect the compounding opt-in gates that limit real-world exposure.

"Narrow mainline window and opt-in HTTP/3 cap the blast radius, but edge deployments keep this HIGH."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Identify NGINX with HTTP/3 enabled

The attacker scans for targets advertising alt-svc: h3 headers or discovers open UDP 443 via Shodan/Censys/FOFA. Only NGINX mainline 1.31.0–1.31.1 compiled with --with-http_v3_module and configured with listen 443 quic is reachable. The v4ltonn scanner PoC automates this step using aioquic.
Conditions required:
  • Target runs NGINX 1.31.0 or 1.31.1
  • HTTP/3 QUIC is compiled in and enabled in config
  • UDP 443 is open to the attacker
Where this breaks in practice:
  • 1.31.x is mainline (development), not the stable branch — most production fleets run stable
  • HTTP/3 requires both compile-time flag and explicit config directives
  • Many firewalls and cloud security groups block UDP 443 by default
Detection/coverage: Shodan query http.component:nginx http.headers.alt-svc:h3; Tenable plugin 321538 (remote version check); v4ltonn/CVE-2026-42530 scanner PoC
STEP 02

Establish QUIC connection and open QPACK encoder stream

The attacker initiates a QUIC handshake and opens a unidirectional QPACK encoder stream as part of normal HTTP/3 setup. NGINX allocates an insert_buffer for header compression from this stream's connection pool. This step is standard protocol behavior and carries no anomaly signal.
Conditions required:
  • TLS 1.3 handshake succeeds (QUIC requirement)
  • NGINX worker accepts the connection
Where this breaks in practice:
  • QUIC libraries required (e.g., aioquic, quiche, ngtcp2) — not as trivial as raw TCP exploitation
STEP 03

Close and reopen the encoder stream

The attacker closes the first encoder stream, causing NGINX to free the stream's pool — including the insert_buffer memory. The session-level pointer to this buffer is now dangling. The attacker then opens a second QPACK encoder stream on the same connection. NGINX processes this without checking that the prior stream was already consumed, writing into freed memory. Patched versions (1.31.2+) reject the second encoder stream with QUIC error code 0x103; vulnerable versions accept it and return 0x201.
Conditions required:
  • Vulnerable code path exists (1.31.0–1.31.1)
  • Connection is still alive
Where this breaks in practice:
  • Timing must be right — the freed pool must not be reallocated before the second stream arrives, though in practice NGINX's slab allocator makes this reliable
Detection/coverage: WAF/IDS with QUIC-aware deep inspection may flag duplicate encoder streams, but almost no commercial WAF decodes QUIC today
STEP 04

Trigger worker crash (DoS)

The use-after-free corrupts heap state in the worker process, causing a segfault. NGINX's master process auto-restarts the worker, but sustained malicious connections can keep crashing workers, degrading availability for all sites served by this NGINX instance. This is the reliable impact — no ASLR bypass needed.
Conditions required:
  • Steps 1–3 succeeded
Where this breaks in practice:
  • Workers auto-restart; attacker must sustain the attack to maintain DoS
  • Rate limiting on QUIC connection setup can throttle the attack
Detection/coverage: Monitor NGINX error logs for repeated worker crash/respawn cycles; alert on signal 11 (SIGSEGV) in error.log
STEP 05

Achieve RCE (conditional)

If ASLR is disabled (rare on modern Linux — kernel.randomize_va_space=0), or the attacker can infoleak the heap layout via a side channel, the freed memory can be groomed to place attacker-controlled data at the dangling pointer. On the next dereference, NGINX jumps to attacker-supplied code. This is a theoretical escalation path; no public exploit achieves it.
Conditions required:
  • ASLR disabled or bypassed
  • Attacker can groom the NGINX worker heap
Where this breaks in practice:
  • ASLR is enabled by default on every mainstream Linux distro since ~2005
  • No public heap-grooming technique for this specific NGINX code path exists
  • NGINX workers run as unprivileged nginx or www-data user, limiting post-exploitation value without a second privilege-escalation bug
Detection/coverage: EDR/auditd can detect anomalous child processes spawned from NGINX workers; seccomp profiles on containerized NGINX block execve
03 · Compensating Control

1
HIGH 7.5→IGNORE 0.0
SEVERITY REDUCED
Disable HTTP/3 by removing listen … quic and http3 on directives — Eliminates the attack surface entirely — the vulnerable code path in ngx_http_v3_module is never reached. This is the fastest mitigation and should be deployed within the noisgate mitigation SLA of 30 days (HIGH). If HTTP/3 is not business-critical, this can serve as permanent remediation.
2
HIGH 7.5→IGNORE 0.0
SEVERITY REDUCED
Block UDP 443 at perimeter firewall or cloud security group — Prevents QUIC traffic from reaching NGINX even if HTTP/3 is configured. Deploy within 30 days per the noisgate mitigation SLA. Note: this breaks HTTP/3 for legitimate clients, so coordinate with application owners.
3
HIGH 7.5→IGNORE 0.0
SEVERITY REDUCED
Upgrade to NGINX 1.31.2+ or apply vendor patches for Gateway Fabric / Ingress Controller — The definitive fix. F5 released 1.31.2 on 2026-06-17 — now nearly 4 months old. Per the noisgate remediation SLA of 180 days (HIGH), the patch deadline is 2026-12-14. Prioritize internet-facing instances.
4
HIGH 7.5→MEDIUM 5.5
SEVERITY REDUCED
Rate-limit QUIC connection establishment — Using limit_conn and limit_req or upstream firewall rate limiting on UDP 443 reduces the attacker's ability to sustain repeated worker crashes. Does not eliminate the vulnerability but raises the bar for impactful DoS. Deploy as a bridge control while scheduling patching.
5
HIGH 7.5→HIGH 6.5
Enable seccomp and read-only root filesystem on containerized NGINX — If the conditional RCE path were achieved, seccomp blocks execve and similar syscalls from the worker, and a read-only filesystem prevents payload drops. Already standard in hardened Kubernetes pods.
What doesn't work
  • WAF in front of NGINX — virtually no commercial WAF decodes QUIC/HTTP/3 at the protocol level today. The malicious QPACK encoder stream manipulation happens inside the encrypted QUIC tunnel and is invisible to a TCP-layer WAF.
  • Enabling ASLR — ASLR is already enabled by default everywhere. It mitigates the theoretical RCE escalation but does nothing against the reliable DoS path, which is the primary impact.
  • NGINX proxy_protocol or real_ip restrictions — these operate at HTTP layer after the QUIC handshake; the vulnerability triggers during QUIC stream setup, before any HTTP request is processed.
04 · Intelligence Metadata

The supporting signals.

In-the-Wild ExploitationNo confirmed exploitation. F5 made no mention of active attacks at disclosure (2026-06-17). Not listed in CISA KEV as of 2026-10-07. No GreyNoise tags observed.
Proof-of-Concept AvailabilityScanner/detector PoCs exist. v4ltonn/CVE-2026-42530 (Python/aioquic — sends dual QPACK encoder streams, checks error codes), 0xBlackash/CVE-2026-42530 (Python — safe version checker). Both are detection-only; no weaponized RCE exploit is public.
EPSS0.01145 (~98.5th percentile). Elevated relative to baseline, reflecting the unauthenticated-remote vector, but consistent with no observed exploitation.
CISA KEV StatusNot listed as of 2026-10-07.
CVSS Vectorsv3.1: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H (8.1 HIGH) — AC:H reflects ASLR requirement for RCE. v4.0: 9.2 CRITICAL — inflated by worst-case RCE ceiling without weighting real-world ASLR prevalence.
Affected VersionsNGINX Open Source 1.31.0–1.31.1 (mainline only). Also: Gateway Fabric 2.0.0–2.6.3, Ingress Controller 3.5.0–3.7.2 / 4.0.0–4.0.1 / 5.0.0–5.5.0, Instance Manager 2.17.0–2.22.0.
Fixed VersionsNGINX Open Source 1.31.2 (2026-06-17). Gateway Fabric 2.6.4. Ingress Controller and Instance Manager patches per F5 advisory K000161616.
Scanning / ExposureHTTP/3 advertised via alt-svc: h3 on ~39% of top sites (April 2026 data), but actual QUIC usage is ~21%. The subset running NGINX mainline 1.31.0–1.31.1 with HTTP/3 is a tiny fraction — mainline is a development track, not the stable branch most enterprises deploy.
Disclosure Date2026-06-17 (coordinated with F5 patch release).
ResearcherTrung Nguyen of CyStack. Described root cause as a "lifetime mismatch" between session-scoped pointer and stream-scoped pool allocation.

Sources.

  1. F5 Advisory K000161616
  2. The Hacker News — F5 Patches Two Critical NGINX Flaws
  3. NGINX Security Advisories
  4. NVD — CVE-2026-42530 Detail
  5. v4ltonn/CVE-2026-42530 Scanner PoC (GitHub)
  6. SOCPrime — CVE-2026-42530 Analysis
  7. Penligent — NGINX HTTP/3 QPACK Use-After-Free Deep Dive
  8. CSA Singapore — Alert AL-2026-080
05 · The Call

Final Verdict
= UNCHANGED to HIGH (7.5/10)

Why this verdict

  • Narrow version window: Only mainline 1.31.0 and 1.31.1 are affected — the stable branch that most enterprises deploy is untouched. This dramatically limits the reachable population versus a typical NGINX CVE.
  • Opt-in attack surface: HTTP/3 requires compile-time flag (--with-http_v3_module), explicit config (listen … quic; http3 on;), and open UDP 443. Each gate compounds downward from the vendor baseline.
  • ASLR kills the RCE path: ASLR is universally enabled on modern Linux. The reliable impact is DoS via worker crash, not code execution. Workers auto-restart, so sustained exploitation is needed for meaningful outage.
  • Role multiplier: NGINX canonically occupies the network edge high-value role (reverse proxy, load balancer, API gateway, Kubernetes ingress). On an internet-facing NGINX ingress controller running 1.31.x with HTTP/3, a sustained DoS takes down all upstream services — blast radius is tenant/cluster-scale. The NGINX Ingress Controller's wide affected range (3.5.0–5.5.0) means the Kubernetes deployment scenario is real, not hypothetical. This floors the verdict at HIGH despite the opt-in gates.
  • No exploitation uplift: No KEV listing, no observed in-the-wild exploitation, no weaponized RCE PoC. Only safe-check scanner PoCs exist. This supports staying at the floor rather than above it.

Why not higher?

The CVSS v4.0 score of 9.2 / CRITICAL over-counts RCE impact that depends on ASLR being disabled — a configuration essentially extinct in production Linux. The reliable impact is DoS with auto-recovery, not persistent compromise. The narrow mainline-only version range means the installed base is a fraction of total NGINX deployments; a CRITICAL rating would over-allocate patching urgency relative to CVEs hitting the stable branch.

Why not lower?

NGINX is a canonical edge component and the Ingress Controller's wide affected version range means Kubernetes clusters are in scope. Unauthenticated remote DoS of an edge proxy or ingress controller is operationally significant — even with auto-restart, sustained attacks degrade availability for every service behind it. The existence of working scanner PoCs lowers the skill bar for discovery. Dropping below HIGH would under-weight the deployment-role blast radius.

06 · Verification

Crowdsourced verification payload.

Run this script on each NGINX host as any user with read access to the NGINX binary and config. Invoke with: bash check_cve_2026_42530.sh. No root required unless the NGINX binary path is restricted.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_42530.sh — Detect CVE-2026-42530 exposure
# Checks: (1) NGINX version in affected range, (2) HTTP/3 module compiled in, (3) HTTP/3 enabled in config
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -euo pipefail

NGINX_BIN="${1:-$(command -v nginx 2>/dev/null || echo '')}"

if [[ -z "$NGINX_BIN" ]]; then
  echo "UNKNOWN — nginx binary not found in PATH. Pass path as argument."
  exit 2
fi

# Get version
VER_LINE=$($NGINX_BIN -v 2>&1 || true)
VER=$(echo "$VER_LINE" | grep -oP 'nginx/\K[0-9]+\.[0-9]+\.[0-9]+' || echo '')

if [[ -z "$VER" ]]; then
  echo "UNKNOWN — could not parse NGINX version from: $VER_LINE"
  exit 2
fi

echo "[*] NGINX version: $VER"

# Check if version is in affected range (1.31.0 or 1.31.1)
case "$VER" in
  1.31.0|1.31.1)
    AFFECTED=1
    ;;
  *)
    echo "PATCHED — version $VER is outside affected range (1.31.0–1.31.1)."
    exit 0
    ;;
esac

# Check if http_v3_module is compiled in
BUILD_FLAGS=$($NGINX_BIN -V 2>&1 || true)
if echo "$BUILD_FLAGS" | grep -q 'http_v3_module'; then
  echo "[!] HTTP/3 module (ngx_http_v3_module) is compiled into this binary."
  H3_COMPILED=1
else
  echo "PATCHED — version $VER is affected but ngx_http_v3_module is NOT compiled in. Not exploitable."
  exit 0
fi

# Check if HTTP/3 is enabled in running config
CONFIG_DUMP=$($NGINX_BIN -T 2>/dev/null || echo 'CONFIG_UNREADABLE')
if [[ "$CONFIG_DUMP" == "CONFIG_UNREADABLE" ]]; then
  echo "VULNERABLE — version $VER with http_v3_module compiled in. Could not read config to check if HTTP/3 is active (run as root or nginx user). Assume vulnerable."
  exit 1
fi

if echo "$CONFIG_DUMP" | grep -qE 'listen.*quic|http3\s+on'; then
  echo "VULNERABLE — NGINX $VER with HTTP/3 (QUIC) enabled in configuration. CVE-2026-42530 is exploitable."
  exit 1
else
  echo "PATCHED — version $VER with http_v3_module compiled in but HTTP/3 is NOT enabled in config. Not currently exploitable."
  exit 0
fi