Like a bouncer who measures you for a coat then hands you a parka three sizes too big — your closet overflows
NGINX's script engine evaluates complex string expressions in two passes: a length pass that measures how much memory to allocate, and a copy pass that writes the actual bytes. When a map directive uses a regex with numbered capture groups ($1, $2) and the result string references those captures *before* the map output variable, evaluating the map's own regex between passes silently replaces the shared r->captures state. The length pass measured a 1-byte capture; the copy pass now writes 16+ bytes from the clobbered capture into that 1-byte allocation — a textbook heap buffer overflow in the NGINX worker process. This affects every NGINX Open Source version from 0.9.6 through 1.31.2 and every NGINX Plus release through R36/37.0.0.1 — a 15-year window since map gained regex support in March 2011. Fixed in nginx 1.30.4 (stable), 1.31.3 (mainline), NGINX Plus R36 P7, and 37.0.3.1.
F5's CVSS v3.1 score of 8.1 (HIGH) with Attack Complexity: High reflects the configuration prerequisite: the target must use a regex-based map with numbered captures in the specific vulnerable ordering. That prerequisite is real. But the vendor score under-weights three factors. First, weaponized PoC code (imbas007, 0xCyberstan, DepthFirstDisclosures/Nginx-Rift) has been public since July 27, 2026, and chains an info-leak primitive to defeat ASLR on stock Ubuntu 24.04 with claimed "10/10 reliability." Second, NGINX's canonical deployment role is network edge: reverse proxy, load balancer, Kubernetes Ingress Controller, API gateway. Compromising that tier exposes TLS private keys, all transit traffic, session tokens, and upstream service credentials — a data-plane-wide blast radius. Third, the CVSS v4.0 score F5 themselves assigned is 9.2 CRITICAL, acknowledging the same reality. The v3.1 score's HIGH label is what most scanners display, and it understates the operational risk.
5 steps from start to impact.
Identify NGINX target and version
Server response headers or default error page footers. Shodan, Censys, and FOFA index millions of NGINX instances globally (~33% of all web servers). Version strings in the 0.9.6–1.30.3 (stable) or 1.31.0–1.31.2 (mainline) range are vulnerable.- Internet-reachable NGINX instance
- Version header not suppressed or probeable via error pages
- Many hardened deployments strip the
Serverheader, forcing blind exploitation - Version alone does not confirm the vulnerable
mapconfiguration is present
CVE-2026-42533 performs version-range matching with dual matchers for stable and mainline branches. Qualys, Tenable, and Rapid7 have published detection plugins.Probe for vulnerable map+regex configuration
map directive with numbered capture groups in the vulnerable evaluation order. Observable side effects include worker crashes (HTTP 502 responses) or memory-disclosure artifacts in response headers. The Sn1per configuration-audit nuclei template checks for the three required code patterns.- Target must use
mapwith regex and numbered captures ($1,$2) - Capture references must appear before the map output variable in a string expression
- This is a non-default, application-specific configuration pattern
- Many NGINX instances use simple
proxy_passwithoutmapat all - Named captures (
(?<name>...)) are not vulnerable via the primary path
signal 6, free(): invalid next size) are observable in error logs. Anomalous 502-spike patterns are detectable by monitoring.Trigger info leak for ASLR bypass
imbas007/CVE-2026-42533 leak.py, DepthFirstDisclosures/Nginx-Rift stream-module leak.- The leaked value must be reflected in the HTTP response (header, redirect URI, or body)
- The map output must appear in a client-visible response field
- Some configurations only use the map value internally, never reflecting it to the client
- WAF byte-pattern rules may flag non-printable characters in response data
Heap overflow and pool corruption
$1 capture. The copy pass writes this oversized capture beyond the allocated buffer, corrupting the adjacent ngx_pool_t structure's cleanup linked list pointer. POST-body spraying performs heap feng shui, placing a fake ngx_pool_cleanup_s record at a predictable offset. Tools: imbas007/CVE-2026-42533 overflow.py, 0xCyberstan/CVE-2026-42533-POC.- Successful ASLR bypass from Step 3
- Ability to control heap layout via concurrent requests
- Heap layout varies by connection count, module configuration, and OS allocator
- The PoC claims 10/10 reliability on Ubuntu 24.04 but other distributions and custom builds may differ
Hijack cleanup handler for code execution
system() with attacker-controlled arguments, achieving pre-auth RCE as the NGINX worker user (typically www-data or nginx). From the worker process, the attacker has read access to TLS private keys, upstream credentials, and all transit traffic on that data plane.- All prior steps succeeded
- NGINX worker process privileges (typically unprivileged user)
- Worker runs as unprivileged user (not root) by default
- Post-exploitation pivot requires local privilege escalation
- Containerized NGINX (K8s pods) limits lateral movement unless the container is privileged
execve from NGINX worker PID.ngx_http_script_copy_capture_code) and publishes only the bytes actually written, eliminating the two-pass desynchronization entirely.~* pattern(.*)$ $1 with ~* pattern(?<val>.*)$ $val in every map block. This isolates capture state and breaks the primary two-pass clobbering path. Deploy within 3 days if patching is not immediately feasible. Note: researcher Stan Shaw warns that maps defining the *same* named group as the location regex still trigger overflow through a secondary code path, so this is risk reduction, not elimination.signal 6 (SIGABRT), free(): invalid next size, or anomalous 502-spike patterns in NGINX error logs. This enables rapid incident detection but does not prevent exploitation. Configure within 3 days.- Rate limiting — A single crafted request triggers the overflow; rate limits do not prevent it.
- Suppressing the
Serverversion header — Hides the version from casual scanners but does not prevent blind exploitation or version probing via error pages; the vulnerable code path is still reachable. - Relying on ASLR alone — The PoC includes a built-in info-leak primitive that defeats ASLR on stock Ubuntu 24.04. ASLR is not a compensating control for this vulnerability.
- IP-based allowlisting — Most NGINX instances *must* accept traffic from untrusted sources (that is their purpose as a reverse proxy). Allowlisting breaks the product's function.
The supporting signals.
| In-the-wild exploitation | No confirmed campaigns as of 2026-10-07. Not on CISA KEV. Rescana issued an "active exploitation alert" but cited no specific threat actor attribution. No GreyNoise tags observed for this CVE. |
|---|---|
| Proof-of-concept availability | Multiple weaponized PoCs public since 2026-07-27. imbas007/CVE-2026-42533 — pre-auth RCE, crash confirmed on Ubuntu 24.04. 0xCyberstan/CVE-2026-42533-POC — info leak + RCE chain by researcher Stan Shaw. DepthFirstDisclosures/Nginx-Rift — stream-module leak + heap overflow with ASLR bypass. Nuclei detection template available via Sn1per and ProjectDiscovery. |
| EPSS | 0.00894 probability (~85th–90th percentile). Moderate exploitation-likelihood signal — elevated above baseline but not in the top decile. |
| KEV status | Not listed as of 2026-10-07. |
| CVSS v3.1 vector | CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H — Network vector, no auth, no user interaction. AC:H reflects the configuration prerequisite (regex map with numbered captures in specific evaluation order). |
| CVSS v4.0 | 9.2 CRITICAL (vendor-assigned by F5). The v4.0 methodology better captures weaponization context and deployment-role impact. |
| Affected versions | NGINX Open Source 0.9.6–1.30.3 (stable), 0.9.6–1.31.2 (mainline). NGINX Plus R33 and below, R36 below P7, 37.0.0.1 below 37.0.3.1. Also affects NGINX Ingress Controller, Gateway Fabric, App Protect WAF, and Instance Manager. |
| Fixed versions | nginx 1.30.4 (stable), 1.31.3 (mainline), NGINX Plus R36 P7, 37.0.3.1. Check RHEL, Ubuntu, and Debian errata for distro-specific backports. |
| Internet exposure | NGINX powers ~33% of web servers globally (W3Techs, May 2026). Millions of instances indexed on Shodan and Censys. Not all use the vulnerable map+regex pattern, but the sheer installed base means a large absolute number are likely affected. |
| Disclosure and credit | Disclosed 2026-07-15 by F5. Researcher Stan Shaw (0xCyberstan) credited with practical exploitation analysis. DepthFirst Disclosures released the full-chain RCE exploit on 2026-07-28. |
Sources.
- 1w4y.io — CVE-2026-42533 Root Cause and RCE Analysis
- imbas007/CVE-2026-42533 PoC on GitHub
- DepthFirstDisclosures/Nginx-Rift on GitHub
- The Hacker News — Critical NGINX Vulnerability
- Sn1per — CVE-2026-42533 Nuclei Template
- GitHub Advisory GHSA-fxfg-v4rj-hp95
- Red Hat CVE-2026-42533
- 0xCyberstan/CVE-2026-42533-POC on GitHub
Why this verdict
- Baseline is fair. NGINX is one of the most widely deployed software components on the internet (~33% market share). The vendor's CVSS v3.1 baseline of 8.1 (HIGH) is a reasonable starting point for a pre-auth heap overflow with AC:H.
- Weaponized PoC with ASLR bypass eliminates AC:H friction. Three independent public PoCs chain an info-leak primitive with the heap overflow to achieve reliable pre-auth RCE on stock Ubuntu 24.04. The claimed "10/10 reliability" and built-in ASLR bypass mean the practical attack complexity is LOW, not HIGH. This pushes the effective score upward by ~0.5–1.0.
- Configuration prerequisite provides real but bounded friction. The target must use a regex-based
mapdirective with numbered captures in the vulnerable evaluation order. This is non-default but common in production NGINX deployments doing URL rewriting, routing, A/B testing, or geo-steering. The fraction using this pattern is plausibly 10–30% of production deployments. This prevents a 9.8 but does not reduce below CRITICAL. - Role multiplier: NGINX is canonically a network-edge component. The high-value roles — reverse proxy/load balancer at the network edge (the *primary* deployment role), Kubernetes Ingress Controller (the most widely deployed K8s ingress), API gateway (NGINX Plus), WAF (NGINX App Protect) — represent ≥10% of installs *by definition*. The chain succeeds in all these roles. Blast radius: TLS private keys, all transit traffic (auth tokens, API keys, PII), upstream service credentials, pivot into backend tiers. On K8s Ingress: all cluster ingress traffic plus potential pod-escape. This is data-plane-wide compromise → verdict floor is CRITICAL.
- No KEV listing or confirmed campaigns provides slight downward pressure from a 9.8, but weaponized PoC availability with ASLR bypass means exploitation is a matter of when, not if.
Why not higher?
The configuration prerequisite is genuine friction — not every NGINX instance uses map with regex numbered captures. The EPSS score of 0.00894 indicates moderate, not extreme, exploitation likelihood. No confirmed in-the-wild campaigns yet. The worker process runs as an unprivileged user, requiring local privesc for full host takeover beyond the data plane.
Why not lower?
The deployment-role floor rule mandates CRITICAL. NGINX is canonically a network-edge appliance; the majority of its installed base sits at the perimeter or ingress tier. A pre-auth RCE on the data plane with public weaponized exploit code and ASLR bypass cannot be scored below CRITICAL for this class of component. The vendor's own CVSS v4.0 score of 9.2 confirms this assessment. Downgrading to HIGH would require evidence that <1% of NGINX installs use the vulnerable configuration, and no such evidence exists.
Crowdsourced verification payload.
Run on each target host where NGINX is installed, as any user with read access to the nginx binary and configuration files. Example: bash check_cve_2026_42533.sh or bash check_cve_2026_42533.sh /usr/sbin/nginx /etc/nginx/nginx.conf. No elevated privileges required unless nginx.conf is root-readable only.
#!/usr/bin/env bash
# check_cve_2026_42533.sh — CVE-2026-42533 NGINX map regex heap overflow checker
# Usage: bash check_cve_2026_42533.sh [nginx_binary] [nginx_conf]
# Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN
set -euo pipefail
NGINX_BIN="${1:-$(command -v nginx 2>/dev/null || echo '')}"
NGINX_CONF="${2:-/etc/nginx/nginx.conf}"
if [[ -z "$NGINX_BIN" ]]; then
echo "UNKNOWN — nginx binary not found in PATH. Provide path as first argument."
exit 2
fi
if [[ ! -x "$NGINX_BIN" ]]; then
echo "UNKNOWN — $NGINX_BIN is not executable."
exit 2
fi
# Extract version
VERSION_OUTPUT=$($NGINX_BIN -v 2>&1 || true)
VERSION=$(echo "$VERSION_OUTPUT" | grep -oP 'nginx/\K[0-9]+\.[0-9]+\.[0-9]+' | head -1)
if [[ -z "$VERSION" ]]; then
echo "UNKNOWN — could not parse nginx version from: $VERSION_OUTPUT"
exit 2
fi
echo "Detected nginx version: $VERSION"
# Parse version components
IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"
# Version comparison: returns 0 if a >= b
ver_gte() {
local a1=$1 a2=$2 a3=$3 b1=$4 b2=$5 b3=$6
if (( a1 > b1 )); then return 0; fi
if (( a1 < b1 )); then return 1; fi
if (( a2 > b2 )); then return 0; fi
if (( a2 < b2 )); then return 1; fi
if (( a3 >= b3 )); then return 0; fi
return 1
}
# Check version ranges
# Vulnerable: 0.9.6 - 1.30.3 (stable) and 1.31.0 - 1.31.2 (mainline)
# Patched: >= 1.30.4 (stable) or >= 1.31.3 (mainline)
VULN_VERSION=false
if (( MAJOR == 1 && MINOR == 31 )); then
if (( PATCH <= 2 )); then
VULN_VERSION=true
fi
elif (( MAJOR == 1 && MINOR == 30 )); then
if (( PATCH <= 3 )); then
VULN_VERSION=true
fi
elif ver_gte "$MAJOR" "$MINOR" "$PATCH" 0 9 6 && ! ver_gte "$MAJOR" "$MINOR" "$PATCH" 1 30 4; then
VULN_VERSION=true
fi
# Check configuration for vulnerable map+regex pattern
VULN_CONFIG=false
CONFIG_MSG=""
if [[ -r "$NGINX_CONF" ]]; then
FULL_CONF=$($NGINX_BIN -T 2>/dev/null || cat "$NGINX_CONF" 2>/dev/null || echo "")
if echo "$FULL_CONF" | grep -qP 'map\s+.*\{' && \
echo "$FULL_CONF" | grep -qP '~[*]?\s+.*\([^?]' && \
echo "$FULL_CONF" | grep -qP '\$[0-9]+'; then
VULN_CONFIG=true
CONFIG_MSG="Vulnerable map+regex pattern with numbered captures DETECTED in configuration."
else
CONFIG_MSG="No vulnerable map+regex pattern with numbered captures found in configuration."
fi
else
CONFIG_MSG="Could not read $NGINX_CONF — configuration check skipped."
fi
# Final verdict
if $VULN_VERSION; then
if $VULN_CONFIG; then
echo "VULNERABLE — nginx $VERSION is in the affected range AND vulnerable configuration pattern detected."
echo "$CONFIG_MSG"
echo "Action: Upgrade to nginx >= 1.30.4 (stable) or >= 1.31.3 (mainline) immediately."
exit 1
else
echo "VULNERABLE — nginx $VERSION is in the affected range."
echo "$CONFIG_MSG"
echo "Note: Version is vulnerable but the specific map+regex pattern was not detected."
echo "Action: Upgrade to nginx >= 1.30.4 (stable) or >= 1.31.3 (mainline)."
exit 1
fi
else
echo "PATCHED — nginx $VERSION is not in the affected version range."
exit 0
fi