← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2026-9256 · CWE-122 · Disclosed 2026-05-22

NGINX Plus and NGINX Open Source have a vulnerability in the ngx_http_rewrite_module module

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a loaded trapdoor that only opens if your rewrite rules were built in exactly the wrong shape

CVE-2026-9256 is a heap-based buffer overflow in NGINX ngx_http_rewrite_module triggered when a rewrite directive combines *overlapping PCRE captures* with a replacement string that references multiple captures in a redirect or arguments context. Upstream marks Open Source NGINX 0.1.17 through 1.31.0 as vulnerable and 1.31.1+ / 1.30.2+ as fixed; the same bug also affects corresponding NGINX Plus builds, with vendor-fixed releases at R32 P7, R36 P5, and 37.0.1.1.

The vendor's HIGH rating is technically understandable because the bug is unauthenticated and sits on the data plane, but it overshoots most enterprise reality. The decisive friction is *configuration specificity*: an attacker only gets leverage if your live config contains the exact rewrite pattern shape, and even then the common result on modern Linux is worker crash/restart, while true RCE needs ASLR disabled or a separate ASLR bypass.

"Internet-reachable, yes; broadly weaponizable, no. This bug needs a very specific rewrite pattern and modern hosts mostly turn RCE into crashes."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Find an exposed NGINX edge with vulnerable code

The attacker first needs an internet-reachable NGINX instance running a vulnerable build such as 1.31.0 or 1.30.1. Commodity recon tools like httpx or nmap can fingerprint banners, but version data alone is not enough because exploitability depends on the deployed rewrite rules, not just the binary.
Conditions required:
  • Unauthenticated remote network access to the HTTP service
  • Target is running vulnerable NGINX Open Source or NGINX Plus code
  • Banner suppression or reverse-proxy layering does not fully hide the product
Where this breaks in practice:
  • Many enterprise deployments suppress exact version strings
  • A vulnerable binary is not exploitable unless the live config uses the dangerous rewrite pattern
  • Some fleets terminate traffic on another edge before requests ever reach the affected NGINX tier
Detection/coverage: Version scanners will over-report. Network scanners can often detect NGINX, but they usually cannot prove the dangerous rewrite condition from the outside.
STEP 02

Reach a location that executes the bad rewrite

The attacker must send requests into a location whose rewrite rule uses overlapping captures and multiple backreferences in a redirect or query-string context. The commit for 3f135ae shows the failing pattern class directly, and a simple curl-style request is enough once the right route is found.
Conditions required:
  • A matching rewrite directive exists in the active config
  • The regex contains overlapping captures such as nested groups
  • The replacement string references multiple captures such as $1$2
Where this breaks in practice:
  • This is a narrow config shape, not a default NGINX behavior
  • Many rewrite rules are generated from templates and may not use overlapping captures at all
  • Attackers usually need some path discovery or source leakage to find the affected route
Detection/coverage: External scanning is weak. Best coverage comes from config audit with nginx -T plus static pattern matching for nested capture groups and multi-backreference replacements.
STEP 03

Trigger heap corruption in a worker

Once the bad rewrite path is reached, a crafted HTTP request can cause the rewrite engine to allocate a buffer smaller than the replacement string needs. In normal hardened deployments this most plausibly produces worker crash/restart or request failure, which is still operationally visible but usually self-healing.
Conditions required:
  • Request reaches the vulnerable rewrite path
  • The vulnerable code path is exercised in redirect or args handling
  • Worker process handles the request before rate limits or upstream blocks intervene
Where this breaks in practice:
  • Worker isolation limits blast radius compared with a monolithic daemon crash
  • Auto-restart behavior can turn single-shot exploitation into noisy instability instead of durable compromise
  • Rate limiting, CDN shielding, and upstream proxying can reduce request delivery volume
Detection/coverage: Look for worker process restarts, segfaults, core dumps, elevated 5xx on specific URIs, and correlated bursts of malformed requests in NGINX access/error logs.
STEP 04

Turn memory corruption into code execution

RCE is the theoretical top-end outcome, but the vendor and NVD both explicitly gate that on systems with ASLR disabled or where the attacker can bypass ASLR. That moves practical exploitation out of the 'spray the internet' category and into a much smaller set of weakly hardened or already-compromised environments.
Conditions required:
  • ASLR is disabled, weakened, or bypassed
  • The attacker can shape memory reliably enough for control
  • Process-level mitigations do not break exploitation
Where this breaks in practice:
  • Modern Linux servers usually have ASLR enabled by default
  • Memory-corruption reliability across heterogeneous fleets is hard
  • EDR, crash collection, and service watchdogs raise noise during repeated attempts
Detection/coverage: There is no trustworthy remote scanner for the RCE condition. Host telemetry around repeated crashes, coredumps, seccomp violations, or anomalous child process behavior is the best signal.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo confirmed exploitation found in primary sources reviewed. The CISA KEV catalog does not list CVE-2026-9256 as of this assessment.
Proof-of-concept availabilityNo mature public exploit repo located in primary sources. However, the upstream fix commit and Openwall disclosure provide enough detail for a competent operator to build a crash PoC quickly.
EPSS0.00076 from the user-supplied intel block — extremely low, consistent with a bug that is reachable from the network but gated by a narrow configuration prerequisite.
KEV statusNot KEV-listed. No published KEV due date, no CISA exploitation designation, and no primary-source campaign reporting located.
CVSS and what it missesVendor/CNA scores it 8.1 HIGH with CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H; NVD also shows a CNA-supplied CVSS v4.0 9.2. The miss is that CVSS treats the attack as network-exploitable but does not meaningfully model the *specific rewrite-rule shape* required in live configs.
Affected versionsUpstream NGINX security advisories mark Open Source 0.1.17-1.31.0 as vulnerable. Corresponding NGINX Plus trains are covered by the vendor advisory referenced by NVD.
Fixed versions and backportsUpstream fixes are 1.31.1+ and 1.30.2+; NGINX Plus fixed builds are R32 P7, R36 P5, and 37.0.1.1 per vendor-linked advisories. Downstream examples: Ubuntu lists fixed package backports across supported LTS releases, and OpenResty 1.29.2.5 backports the patch.
Researcher / reportingThe NGINX CHANGES entry credits Mufeed VH of Winfunc Research. The fix commit also documents the triggering configuration examples.
Disclosure timelineDisclosed 2026-05-22. NVD shows publication on May 22, 2026, and upstream released 1.31.1 and 1.30.2 the same day.
Scanning / exposure realityExposure is likely broad at the product level but narrow at the exploitable-path level. Public internet scanners can find lots of NGINX, but none of the primary sources reviewed provide GreyNoise/Shodan/Censys evidence that the exact vulnerable rewrite pattern is being mass-scanned or broadly fingerprinted. Treat internet-facing NGINX as the population; treat the dangerous rewrite shape as the true exploitable subset.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to MEDIUM (6.3/10)

The single biggest downward pressure is that exploitation requires a *very specific live rewrite-rule pattern*, not merely a vulnerable NGINX version on the internet. On modern hardened Linux, the most common practical outcome is worker crash/restart rather than reliable remote code execution, and there is no primary-source evidence of active exploitation.

HIGH Affected-version and fixed-version boundaries
MEDIUM Real-world exploitability across a typical enterprise fleet
MEDIUM Assessment that most impact will be DoS/instability rather than RCE

Why this verdict

  • Downgraded for config-specific reachability: the attacker needs a narrow rewrite pattern with overlapping captures plus multiple backreferences; most NGINX installs will not meet that prerequisite.
  • Downgraded for exploitation reliability: vendor text itself conditions code execution on ASLR being disabled or bypassed, which cuts against broad internet-scale RCE in modern fleets.
  • Upward pressure remains because it is unauthenticated and edge-facing: if the bad rewrite exists on a public route, the attacker does not need credentials or user interaction to hit it.
  • No exploitation pressure today: no KEV listing, no primary-source campaign reporting, and the user-supplied EPSS is extremely low.
  • Worker-process blast radius is usually bounded: the common operational failure mode is a worker restart or crash, which matters for availability but is not the same as durable host takeover.

Why not higher?

This is not a straight-line unauthenticated RCE against every exposed NGINX server. A vulnerable binary is only part of the story; the exploit path also needs a precise rewrite configuration shape and, for the worst-case outcome, weak or bypassed memory-randomization defenses.

Why not lower?

The bug still lives in a public request-processing path on one of the most widely deployed edge servers in enterprise estates. If your config does contain the bad rewrite pattern, an unauthenticated remote party can trigger memory corruption with no foothold, so this is not backlog trivia.

05 · Compensating Control

What to do — in priority order.

  1. Audit live rewrite rules — Run nginx -T across internet-facing NGINX and search for nested capture groups combined with multiple backreferences in rewrite replacements, especially redirects and query-string rewrites. For a MEDIUM finding there is no mitigation SLA — go straight to the 365-day remediation window, but this audit should happen in the next normal engineering cycle because it determines whether the bug is actually reachable in your fleet.
  2. Prefer simple rewrites or non-capturing groups — Where business logic allows, replace overlapping capture designs with simpler regex or non-capturing groups so that a vulnerable version loses the dangerous trigger condition. There is no mitigation SLA for this bucket, so treat it as a normal-change hardening task while you work through patching.
  3. Keep ASLR fully enabled — Validate kernel.randomize_va_space=2 and avoid local hardening exceptions that weaken user-space randomization. This does not remove the bug, but it materially degrades the path from crash to code execution; for MEDIUM, do it in ordinary platform hygiene work rather than as an emergency change.
  4. Watch for worker crash patterns — Alert on NGINX worker restarts, segfaults, coredumps, and URI-specific 5xx spikes so you can distinguish opportunistic fuzzing from normal traffic anomalies. This is the most useful near-term detective control when version-only asset data cannot tell you whether the vulnerable rewrite exists.
What doesn't work
  • A generic WAF signature does not solve this well; the trigger is tied to your server-side rewrite logic, not a stable payload pattern with one clean IOC.
  • Version-only scanning is necessary but insufficient; it tells you which binaries are old, not whether the dangerous rewrite shape is present.
  • 'No control plane exposure' reasoning is irrelevant; the vendor explicitly states this is a *data plane* issue, so management-plane isolation does not reduce exploitability.
  • ASLR alone is not a fix; it mainly suppresses the RCE path, but the crash/DoS path still exists on vulnerable and reachable configs.
06 · Verification

Crowdsourced verification payload.

Run this on the target NGINX host or inside the container image that actually serves traffic. Invoke it as sudo bash ./check-cve-2026-9256.sh because it needs nginx -v and ideally nginx -T access to the loaded config; it prints PATCHED, VULNERABLE, or UNKNOWN and exits 0, 1, or 2 respectively.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2026-9256.sh
# Detect likely exposure to CVE-2026-9256 (NGINX ngx_http_rewrite_module overlapping captures)
# Exit codes:
#   0 = PATCHED
#   1 = VULNERABLE
#   2 = UNKNOWN

set -u

patched_mainline_min="1.31.1"
patched_stable_min="1.30.2"
mainline_floor="1.31.0"

have_cmd() { command -v "$1" >/dev/null 2>&1; }

ver_ge() {
  # returns 0 if $1 >= $2
  [ "$(printf '%s\n%s\n' "$2" "$1" | sort -V | head -n1)" = "$2" ]
}

ver_lt() {
  # returns 0 if $1 < $2
  ! ver_ge "$1" "$2"
}

extract_version() {
  local raw
  raw="$(nginx -v 2>&1)" || return 1
  printf '%s' "$raw" | sed -n 's#.*nginx/\([0-9][0-9.]*\).*#\1#p'
}

if ! have_cmd nginx; then
  echo "UNKNOWN: nginx binary not found in PATH"
  exit 2
fi

version="$(extract_version)"
if [ -z "${version:-}" ]; then
  echo "UNKNOWN: could not parse nginx version"
  exit 2
fi

# Patched version logic:
# - mainline fixed at 1.31.1+
# - stable fixed at 1.30.2+ and < 1.31.0
if ver_ge "$version" "$patched_mainline_min"; then
  echo "PATCHED: nginx version $version is >= $patched_mainline_min"
  exit 0
fi

if ver_ge "$version" "$patched_stable_min" && ver_lt "$version" "$mainline_floor"; then
  echo "PATCHED: nginx version $version is in the fixed stable range >= $patched_stable_min and < $mainline_floor"
  exit 0
fi

# Vulnerable code train. Now check whether config appears to contain the risky rewrite pattern.
config_dump="$(nginx -T 2>&1)"
nginx_t_rc=$?
if [ $nginx_t_rc -ne 0 ] || [ -z "$config_dump" ]; then
  echo "UNKNOWN: nginx version $version is vulnerable-by-version, but 'nginx -T' could not be read"
  exit 2
fi

# Heuristic checks only. We look for rewrite lines with:
# - nested capture groups like ((...))
# - multiple backreferences in replacement like $1$2
# - redirect or query-string usage, which upstream says are relevant contexts
suspicious_lines="$(printf '%s\n' "$config_dump" | awk '
  BEGIN { IGNORECASE=1 }
  /^[[:space:]]*rewrite[[:space:]]+/ {
    line=$0
    nested = (line ~ /\(\([^)]*\*[^)]*\)\)/ || line ~ /\(\(.*\)\)/)
    multibackref = (line ~ /\$[0-9].*\$[0-9]/)
    redirectish = (line ~ /redirect[[:space:]]*;/ || line ~ /\?.*\$[0-9]/)
    if (nested && multibackref && redirectish) print line
  }
')"

if [ -n "$suspicious_lines" ]; then
  echo "VULNERABLE: nginx version $version is vulnerable and suspicious rewrite directives were found"
  printf '%s\n' "$suspicious_lines" | sed 's/^/MATCH: /'
  exit 1
fi

echo "UNKNOWN: nginx version $version is vulnerable-by-version, but no obvious matching rewrite directives were found by heuristic scan"
exit 2
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do two things: inventory every internet-facing NGINX/NGINX Plus instance still on vulnerable code trains and run a live-config audit for risky rewrite rules, because that prerequisite is what separates noise from real exposure here. For this MEDIUM assessment there is noisgate mitigation SLA: no mitigation SLA — go straight to the 365-day remediation window; use that window to move exposed systems to 1.31.1+, 1.30.2+, or the corresponding Plus fixed release, while prioritizing public-facing hosts with suspicious rewrite patterns first under the noisgate remediation SLA.

Sources

  1. NVD CVE-2026-9256
  2. NGINX security advisories
  3. NGINX CHANGES
  4. NGINX fix commit 3f135ae
  5. Openwall disclosure thread
  6. Ubuntu CVE tracker
  7. Debian security tracker
  8. OpenResty 1.29.2.5 release
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.