This is a hidden crack in the front gate, but only if your gate was welded in one very specific pattern
CVE-2026-42945 is a heap buffer overflow in NGINX's ngx_http_rewrite_module affecting 0.6.27 through 1.30.0. The trigger is not just 'NGINX is installed': the vulnerable path needs a rewrite replacement string containing ?, followed by a rewrite, if, or set that reuses an unnamed PCRE capture such as $1 or $2. A crafted HTTP request can then desynchronize length calculation from copy behavior and crash a worker; code execution is possible if ASLR is disabled or bypassed.
The vendor's HIGH 8.1 baseline is directionally fair, but the raw score overstates how many real deployments are actually exploitable. This is *unauthenticated remote* on a very common edge service, which keeps it important, yet the reachable population is materially reduced by the configuration precondition and by the fact that the scary RCE outcome is not the default outcome on modern hardened hosts. Net: keep it HIGH, but not CRITICAL.
4 steps from start to impact.
Find a reachable NGINX edge with risky rewrite logic
ngx_http_rewrite_module. The public write-up and PoC from DepthFirstDisclosures/Nginx-Rift show the vulnerable logic only exists when rewrite processing uses the exact state-changing sequence involving ? and later capture reuse.- Unauthenticated network reachability to the NGINX listener
- NGINX version in
0.6.27-1.30.0 - A live request path that hits vulnerable rewrite rules
- Not every NGINX deployment uses rewrite rules at all
- Even when rewrite is used, the rule chain must include the specific
?plus capture-reuse pattern
nginx -T output for the rewrite pattern.Trigger the length/copy mismatch with crafted URI data
Nginx-Rift PoC, the attacker sends a request whose URI and query semantics force NGINX's script engine into an undersized heap allocation. The bug is caused by is_args state being set during rewrite handling, while a later length-calculation pass uses a zeroed sub-engine and underestimates how much escaped data will be written.- The request must match the target rewrite regex
- The request URI must contain characters that expand under
NGX_ESCAPE_ARGS
- This is not a generic one-packet smash against every endpoint
- Attackers need rule-aware request shaping, not just host discovery
Convert overflow into worker crash or memory corruption
- Sufficient heap shaping to land near useful structures
- Ability to retry against restarted workers
- A crash is easier than RCE, but repeated visible worker failures raise operational noise
- Heap shaping is still exploitation work, not commodity spraying
worker process exited on signal / abnormal worker restarts, core dumps, and bursts of malformed-path requests.Escalate from DoS to RCE only on weakened hosts
ngx_pool_t corruption and cleanup-handler control, then relies on ASLR being disabled or otherwise bypassed. That means the headline 'RCE' is real in lab conditions, but the default modern enterprise server outcome is more often denial of service than turnkey code execution.- ASLR disabled, or an independent ASLR bypass/leak
- Successful corruption of a usable cleanup pointer path
- Modern distro hardening materially raises the bar
- The PoC README itself frames working RCE around ASLR-off conditions
The supporting signals.
| In-the-wild status | No authoritative confirmation found from CISA KEV or NGINX/F5 that this CVE is actively exploited as of this assessment. Some secondary reports claim canary hits, but treat those as unverified until corroborated. |
|---|---|
| Public PoC | Yes. DepthFirstDisclosures/Nginx-Rift on GitHub publishes a working PoC and exploitation notes, which meaningfully lowers attacker effort. |
| EPSS | 0.00897 (~0.897%) from the user-provided intel. That is *low* relative to routinely mass-exploited edge CVEs; percentile was not independently verified from the current FIRST API during this session. |
| KEV status | Not listed in the current CISA Known Exploited Vulnerabilities catalog reviewed for this assessment. |
| CVSS vector reality check | AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H is technically plausible, but the biggest real-world modifier is not AC:H alone; it is the config-dependent reachable population. |
| Affected versions | Official NGINX advisories list vulnerable versions as 0.6.27-1.30.0. |
| Fixed versions | Official NGINX release notes show fixes in Open Source 1.30.1 and 1.31.0. The public PoC README, citing the vendor advisory, also lists NGINX Plus fixes as R36 P4, R35 P2, and R32 P6. |
| Exposure gating | The official rewrite-module docs confirm the exact building blocks involved: rewrite, if, set, unnamed captures like $1..$9, and ? query-string behavior. Inference: this means exposure is broad across NGINX estates, but exploitability is narrower than 'all internet-facing NGINX'. |
| Disclosure timeline | Disclosed on 2026-05-13 with NGINX 1.30.1 and 1.31.0 releases the same day. DepthFirst states it reported the issue to NGINX on 2026-04-21. |
| Detection coverage | Most scanners can catch the vulnerable version, but few will catch the exploitable subset because that requires config inspection of nginx.conf and included files, not just package inventory. |
noisgate verdict.
The decisive factor is that exploitability depends on a *specific rewrite-rule pattern*, not just an exposed NGINX version. That knocks this down from edge-RCE panic territory, but it stays HIGH because the bug is unauthenticated, remote, and sits on one of the most common internet-facing control planes in enterprise estates.
Why this verdict
- Unauthenticated remote, but not universal: no creds or user action are needed, yet the reachable population is limited to requests that traverse a vulnerable rewrite-rule chain.
- Configuration precondition is the real brake: you need
rewritewith?followed byrewrite/if/setreusing unnamed captures like$1, which many NGINX installs simply do not have. - RCE is conditional, DoS is easier: the public research shows worker crash is the default practical impact, while reliable code execution needs ASLR disabled or bypassed.
Why not higher?
This is not a clean all-default internet RCE across every exposed NGINX listener. The exploit chain narrows materially at two points: first on configuration shape, then again on host hardening for the RCE outcome. Those are meaningful brakes in a 10,000-host estate.
Why not lower?
Even with the config gating, this still lands on unauthenticated edge infrastructure that often fronts business-critical applications. A public PoC exists, vulnerable versions span a huge historical window, and worker-crash impact is operationally real even where RCE is blocked.
What to do — in priority order.
- Hunt risky rewrite chains — Search
nginx -Toutput and config management repos for arewritereplacement containing?followed byrewrite,if, orsetreusing$1..$9. Do this first on internet-facing reverse proxies and ingress tiers, and complete it within 30 days. - Remove or refactor vulnerable rule patterns — Where you cannot patch immediately, rewrite rules to avoid the exact stateful sequence described in the advisory, especially unnamed captures reused after a
rewrite ... ?.... Treat this as the temporary risk reduction step and deploy it within 30 days. - Keep platform hardening on — Verify ASLR and standard distro hardening remain enabled on NGINX hosts. This does not stop the bug, but it materially blocks the public RCE path and should be validated within 30 days.
- Alert on worker crash loops — Add or tune detections for abnormal NGINX worker exits, rapid respawns, and path-heavy request bursts against rewrite-heavy locations. This gives you a chance to catch exploitation attempts while patch rollout completes, and should be in place within 30 days.
WAF-onlythinking does not solve this; the exploit rides normal URI processing inside NGINX and a WAF usually lacks the server-side rule context that makes the path vulnerable.Asset inventory without config inspectionis insufficient; version data tells you who is patchable, not which vulnerable nodes are actually exploitable.Worker auto-restartis not a mitigation; it helps availability somewhat, but the public research explicitly uses restart behavior to retry against predictable worker layouts.
Crowdsourced verification payload.
Run this on the target NGINX host as root or with sufficient privileges to execute nginx -T and read included configs. Save it as check-cve-2026-42945.sh and run sudo bash check-cve-2026-42945.sh; it outputs VULNERABLE, PATCHED, or UNKNOWN and exits with 0, 1, or 2 respectively.
#!/usr/bin/env bash
# check-cve-2026-42945.sh
# Defensive verifier for CVE-2026-42945 (NGINX rewrite-module heap overflow)
# Exit codes:
# 0 = VULNERABLE
# 1 = PATCHED
# 2 = UNKNOWN
set -u
TMPFILE="$(mktemp /tmp/nginx42945.XXXXXX 2>/dev/null || echo /tmp/nginx42945.$$)"
cleanup() {
rm -f "$TMPFILE" 2>/dev/null || true
}
trap cleanup EXIT
ver_lt() {
# returns 0 if $1 < $2
[ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -n1)" != "$2" ] && return 1
[ "$1" = "$2" ] && return 1
return 0
}
ver_ge() {
# returns 0 if $1 >= $2
ver_lt "$1" "$2" && return 1
return 0
}
if ! command -v nginx >/dev/null 2>&1; then
echo "UNKNOWN: nginx binary not found"
exit 2
fi
VER_RAW="$(nginx -v 2>&1 || true)"
VER="$(printf '%s' "$VER_RAW" | sed -n 's#.*nginx/\([0-9][0-9.]*\).*#\1#p')"
if [ -z "$VER" ]; then
echo "UNKNOWN: could not parse nginx version from: $VER_RAW"
exit 2
fi
# Fixed upstream in 1.30.1 stable / 1.31.0 mainline. For practical sorting,
# any version >= 1.30.1 is considered fixed upstream for this CVE.
if ver_ge "$VER" "1.30.1"; then
echo "PATCHED: nginx version $VER is at or above upstream fix boundary"
exit 1
fi
# Ancient versions before 0.6.27 are outside the published affected range.
if ver_lt "$VER" "0.6.27"; then
echo "PATCHED: nginx version $VER is below published affected range"
exit 1
fi
if ! nginx -T >"$TMPFILE" 2>&1; then
echo "UNKNOWN: nginx -T failed; version $VER is vulnerable range but config could not be inspected"
exit 2
fi
# Heuristic config checks:
# 1) any rewrite replacement containing '?'
# 2) any later rewrite/if/set use of unnamed capture vars $1..$9
# This is intentionally conservative; absence of a match is UNKNOWN, not PATCHED.
HAS_Q_REWRITE=0
HAS_CAPTURE_REUSE=0
if grep -En '^[[:space:]]*rewrite[[:space:]].*\?.*;' "$TMPFILE" >/dev/null 2>&1; then
HAS_Q_REWRITE=1
fi
if grep -En '^[[:space:]]*(rewrite|if|set)[[:space:]].*\$[1-9]' "$TMPFILE" >/dev/null 2>&1; then
HAS_CAPTURE_REUSE=1
fi
if [ "$HAS_Q_REWRITE" -eq 1 ] && [ "$HAS_CAPTURE_REUSE" -eq 1 ]; then
echo "VULNERABLE: nginx $VER is in affected range and config shows likely risky rewrite/capture pattern"
exit 0
fi
# Optional stronger hint: show whether rewrite module appears in active config.
if grep -En '^[[:space:]]*(rewrite|if|set)[[:space:]]' "$TMPFILE" >/dev/null 2>&1; then
echo "UNKNOWN: nginx $VER is in affected range and rewrite logic exists, but the risky pattern was not confirmed by this heuristic"
exit 2
fi
echo "UNKNOWN: nginx $VER is in affected range, but no rewrite usage was detected by this heuristic; verify templates/includes and packaged backports manually"
exit 2
If you remember one thing.
HIGH after reassessment, use the noisgate mitigation SLA to complete config hunting and any temporary rule refactors within 30 days, then use the noisgate remediation SLA to move every affected host to 1.30.1 / 1.31.0 or the vendor-fixed Plus release within 180 days. If you run externally exposed reverse proxies with heavy rewrite usage, do those first even though there is no authoritative KEV-backed active exploitation signal yet.Sources
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.