A 17-year-old bug in NGINX's map directive turns a niche config pattern into a worker-killing heap smash
CVE-2026-42533 is a heap buffer overflow in NGINX's ngx_http_map_module. It triggers when a map directive uses regex matching and a string expression references the map's regex capture variables (e.g. $1, $2) *before* the map's output variable is dereferenced — or when a non-cacheable variable participates in a string expression under specific conditions. The bug has lived in NGINX since 0.9.6 (circa 2011) and covers every version through 1.31.2, with fixes shipped in 1.30.4 (stable) and 1.31.3 (mainline) on 2026-07-15. Both NGINX Open Source and NGINX Plus (F5) are affected.
F5's HIGH / CVSS 8.1 rating is *directionally* correct but over-indexes on the theoretical C:H/I:H/A:H triad. Real-world impact is almost entirely worker-process crash / restart (DoS) because reliable RCE requires ASLR to be disabled or independently bypassed — an increasingly rare posture on any Linux distro shipped after ~2015. The AC:H metric already reflects the config-dependence: your map block has to look a very specific way for the overflow to reach memory the attacker can influence. We assess HIGH 7.2 — the vendor is close, but the config gating and ASLR gating warrant a small downward nudge.
4 steps from start to impact.
Identify a vulnerable map+regex configuration
Server: header, error page style, or timing, then hunts for URI paths or Host headers that flow through a map directive using ~ (regex) matching. Without config access, this is a black-box guessing game — the attacker probes common patterns (user-agent maps, geo-esque maps, host-based routing).- Reachable NGINX 0.9.6 – 1.31.2 instance
- Target config contains
map $var $out { ~regex ... }with capture-ref-before-output pattern
- The vulnerable config shape is *uncommon* — most
mapblocks reference$outdirectly, not$1/$2before output evaluation - No public scanner fingerprints the bad pattern from outside
Craft a request that drives the overflow
map's regex produces captures that, when interpolated into the string expression, exceed the pre-allocated pool buffer. Because NGINX under-sizes the destination when capture-ref precedes output-var evaluation, the heap write overshoots. No auth, no session.- Unauthenticated HTTP/1.1 or HTTP/2 reachability
- Request field (URI, Host, header) reaches the vulnerable map
AC:H— attacker needs to shape input precisely enough to overflow without first tripping other parsing errors- TLS-terminating load balancers upstream may normalize the offending field
Crash the worker (guaranteed) or attempt RCE (contingent)
master respawns it. Repeat at rate → sustained DoS across all workers. RCE path requires that ASLR is off (or independently bypassed via an info-leak) so the attacker can predict heap layout and land a controlled write on a function pointer / vtable inside the pool.- For DoS: repeatable trigger
- For RCE: ASLR disabled OR separate info-leak primitive
- Modern Linux ships ASLR on by default; kernel.randomize_va_space=2 is the norm
- NGINX pool allocator layout is non-trivial to groom remotely without an oracle
- systemd
Restart=will keep the master alive, blunting DoS impact per-request
child process ... exited on signal 11 in error.log is the highest-signal indicator.Weaponize edge position (RCE branch only)
proxy_pass headers, and the ability to MITM every session flowing through. Pivots to internal application tiers via already-open upstream sockets.- Successful RCE from step 3
- NGINX runs as reverse proxy / L7 LB rather than static file server
- NGINX workers typically run as
nginx/www-data— no root privilege escalation without a second bug - AppArmor/SELinux profiles on RHEL/Ubuntu constrain post-exploit actions
The supporting signals.
| In-the-wild status | No known exploitation as of 2026-07-16. No KEV listing, no honeypot hits on GreyNoise for post-disclosure day-one probes. |
|---|---|
| Proof-of-concept | No public PoC at time of assessment. F5 SIRT advisory does not include a reproducer. Expect a n1k0/researcher writeup within 2-3 weeks given the trivially auditable nature of the map module diff. |
| EPSS | Not yet scored (disclosed 2026-07-15); expect <1% / <50th percentile for the first 30 days given lack of PoC. |
| KEV status | Not listed. CISA has not added CVE-2026-42533 to the Known Exploited Vulnerabilities catalog. |
| CVSS v3.1 vector | AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H = 8.1 HIGH (F5). AC:H correctly reflects the config-shape prerequisite and precise input crafting. |
| Affected versions | nginx 0.9.6 through 1.31.2 (both Open Source and NGINX Plus). ~17 years of releases affected — check RUNNING binary, not package metadata. |
| Fixed versions | nginx 1.30.4 (stable) and nginx 1.31.3 (mainline). Distro backports: watch RHEL/Debian/Ubuntu security trackers — most had backports within 24-48h historically. |
| Exposure population | NGINX serves ~34% of all websites per W3Techs (2026). Shodan shows ~60M+ internet-facing NGINX banners. The *vulnerable config shape* is a much smaller subset — likely single-digit percent of installs. |
| Disclosure | 2026-07-15, coordinated release via nginx.org/2026.html and F5 advisory K000162097. |
| Credit | F5 SIRT internal discovery (no external researcher named in the advisory as of publication). |
noisgate verdict.
The single most decisive factor is deployment-role blast radius: NGINX sits at the network edge as reverse proxy / TLS terminator on a huge fraction of internet-facing estates, and the flaw is unauthenticated-remote — a canonical high-value-role component floors this at HIGH. It does not clear the CRITICAL bar because RCE requires ASLR disabled or independently bypassed, and the vulnerable map configuration shape is present in only a minority of real deployments.
Why this verdict
- Role multiplier: NGINX at the edge (reverse proxy / L7 LB / API gateway) is the canonical high-value role — successful RCE here yields TLS keys, upstream creds, and MITM of every downstream session. Floors verdict at HIGH.
- Unauthenticated remote (PR:N, UI:N): no credentials, no user interaction; any reachable HTTP listener is in scope. Prevents downgrade below HIGH.
- Config-gated trigger (AC:H): only
mapblocks that reference regex captures *before* the output variable are exploitable — this is not the commonmapidiom. Prevents upgrade to CRITICAL. - ASLR gates RCE: worker DoS is guaranteed; code execution requires ASLR disabled or a separate info-leak. Modern distros default to ASLR on. Prevents upgrade to CRITICAL.
- No PoC, not KEV, EPSS unscored: no exploitation pressure justifying an immediate CRITICAL-tier response. Sustains HIGH rather than escalating.
Why not higher?
CRITICAL requires either KEV/active exploitation or a canonical high-value-role chain that succeeds with default configs. Here the trigger is config-shape-dependent (only a subset of map directives are vulnerable) and the RCE branch is ASLR-gated. Absent a PoC and with the DoS-first impact, this does not clear the CRITICAL bar.
Why not lower?
MEDIUM would ignore that NGINX is the internet's most-deployed web server and sits at the trust boundary of tens of millions of estates. Unauthenticated remote heap corruption in an edge component is definitionally HIGH — even without RCE, worker exhaustion of a reverse proxy is a service-outage event for the applications behind it.
What to do — in priority order.
- Upgrade NGINX to 1.30.4 or 1.31.3 within the noisgate SLA — Vendor fix is the definitive remediation — patch by the noisgate HIGH remediation deadline of 180 days. Verify the *running* worker binary via
nginx -v, not just package metadata; long-uptime hosts often run pre-restart binaries. Deploy across CDN/edge tier first, origin second. - Audit configs for the vulnerable
mappattern within 30 days (noisgate HIGH mitigation SLA) — Grep everynginx.confand included file formap $blocks that use~regex matching AND reference$1/$2/named captures *before* the output variable. Refactor to dereference the output variable first, or replace regex maps with exact-match maps where possible. This eliminates the trigger even on unpatched binaries. - Enforce ASLR on every NGINX host — Confirm
kernel.randomize_va_space=2on every worker host — this pushes the vulnerability from RCE-possible to DoS-only. Bake into your baseline CIS/STIG check. Deadline: within the 30-day mitigation window. - Enable
systemdauto-restart and rate-limit worker respawns —Restart=alwayswithRestartSec=prevents a crashed worker from taking the whole edge offline; combine withStartLimitBurst=to fail-safe under sustained attack. Blunts the DoS impact while patch rolls. - Instrument alerting on
worker process exited on signal 11— The only reliable telemetry for exploitation attempts is repeated segfaults in NGINXerror.log. Ship error.log to your SIEM and alert on >3 signal-11 events per worker per hour. Deploy within 7 days.
- WAF signatures — the malicious input is a syntactically valid HTTP field; there is no attack pattern to signature. WAFs upstream will pass the payload through.
- Rate limiting at the LB — the overflow triggers per single request; rate limits slow DoS but do nothing against a one-shot RCE attempt.
- Disabling
iforrewrite— this CVE lives in themapmodule, notrewrite(that's CVE-2026-9256 and CVE-2026-42945). Turning off rewrite does not remove the map-module code path. - Running NGINX in a container — the worker still processes the request with the full bug surface; container isolation only limits post-exploit lateral movement, not the primitive itself.
Crowdsourced verification payload.
Run on each NGINX host as any user with read access to the binary and config (root recommended for reading /etc/nginx/). Invoke as ./check-cve-2026-42533.sh on the target — no arguments. Exit codes: 0 = PATCHED, 1 = VULNERABLE, 2 = UNKNOWN.
#!/usr/bin/env bash
# noisgate check for CVE-2026-42533 — NGINX map+regex heap overflow
# Usage: ./check-cve-2026-42533.sh (run on the NGINX host)
# Exit: 0 PATCHED | 1 VULNERABLE | 2 UNKNOWN
set -u
NGINX_BIN="$(command -v nginx || echo /usr/sbin/nginx)"
CONF_DIR="${NGINX_CONF_DIR:-/etc/nginx}"
if [[ ! -x "$NGINX_BIN" ]]; then
echo "UNKNOWN: nginx binary not found"
exit 2
fi
# 1) Version check — the running binary, not the package
VER_RAW="$($NGINX_BIN -v 2>&1)"
VER="$(echo "$VER_RAW" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)"
if [[ -z "$VER" ]]; then
echo "UNKNOWN: could not parse nginx version from: $VER_RAW"
exit 2
fi
ver_ge() {
# returns 0 if $1 >= $2 (semver, 3-part)
printf '%s\n%s\n' "$2" "$1" | sort -V -C
}
PATCHED=1
# Fixed: 1.30.4+ on stable branch, 1.31.3+ on mainline
MAJOR_MINOR="$(echo "$VER" | awk -F. '{print $1"."$2}')"
case "$MAJOR_MINOR" in
1.30) ver_ge "$VER" "1.30.4" && PATCHED=0 ;;
1.31) ver_ge "$VER" "1.31.3" && PATCHED=0 ;;
*)
# any 1.32+ or later branch is fixed; anything <=1.29 is vulnerable
if ver_ge "$VER" "1.32.0"; then PATCHED=0; fi
;;
esac
# 2) Config heuristic — hunt for map+regex+capture-ref-before-output pattern
CFG_HIT=0
if [[ -r "$CONF_DIR" ]]; then
# crude: any `map $var $out { ... ~... $1|$2 ... }` block
if grep -REn --include='*.conf' -A20 '^\s*map\s+\$[A-Za-z0-9_]+\s+\$[A-Za-z0-9_]+' "$CONF_DIR" 2>/dev/null \
| grep -E '~[^{]*.*\$[1-9]' >/dev/null; then
CFG_HIT=1
fi
fi
echo "nginx version: $VER"
if [[ $PATCHED -eq 0 ]]; then
echo "PATCHED: nginx $VER is not affected by CVE-2026-42533"
exit 0
fi
if [[ $CFG_HIT -eq 1 ]]; then
echo "VULNERABLE: nginx $VER is affected AND config contains map+regex+capture pattern"
else
echo "VULNERABLE: nginx $VER is affected (config-shape trigger not detected but binary is vulnerable)"
fi
exit 1
If you remember one thing.
nginx -v, not the package metadata. Anything 0.9.6–1.31.2 is in scope. Per the noisgate mitigation SLA for HIGH, within 30 days audit configs for map blocks that reference $1/$2 before the output variable and refactor them, confirm ASLR is on everywhere, and enable systemd auto-restart on workers. Per the noisgate remediation SLA for HIGH, roll 1.30.4 (stable) or 1.31.3 (mainline) — or your distro's backport — across the fleet within 180 days, edge tier first. No KEV listing and no PoC yet, so this does not warrant an emergency change window, but a public PoC is likely within 2-3 weeks given how audit-friendly the fix diff is — treat that as a trigger to compress the timeline.Sources
- nginx.org 2026 announcements (disclosure)
- F5 SIRT advisory K000162097
- nginx security advisories index
- NGINX Community Forum — 1.30.4 / 1.31.3 release notes
- LinuxCompatible — 1.31.3 release coverage
- CVE Record (MITRE)
- Related — CVE-2026-9256 (rewrite module) context
- Related — CVE-2026-42945 Akamai analysis (heap overflow class context)
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.