rewrite. A regex with overlapping PCRE captures plus a replacement string that references multiple of them, in a redirect or args context, mishandles the capture data on an unauthenticated request. The edge proxy you trust to be boring has a sharp edge in its busiest config block.
NGINX sits in front of an enormous fraction of the internet, and its rewrite directive is in nearly every non-trivial configuration: canonicalizing URLs, redirecting old paths, rewriting to backends. That ubiquity is exactly why CVE-2026-9256 is worth a careful read: the bug is not in some obscure module, it is in the regex-rewrite machinery operators touch every day.
What the advisory describes
The vulnerability is in the ngx_http_rewrite_module. It manifests when a rewrite directive uses a regex pattern with distinct, overlapping Perl-Compatible Regular Expression (PCRE) captures (the advisory's example is a pattern like ^/((.*))$, where an outer group encloses an inner group) and a replacement string that references multiple of those captures, such as $1$2, in a redirect or arguments context. Under that combination, an unauthenticated request can trigger the flaw in how the captured substrings are handled.
The two conditions worth internalizing are precise: overlapping captures (nested groups that cover the same text), and a replacement that uses more than one of them in a redirect (return 301 ...$1$2) or query-argument context. A configuration that captures once and substitutes once is not in the described shape. The danger is the nested-group-plus-multi-reference pattern, which is common enough (people write ((.*)) by accident, or to group an alternation) that plenty of real configs match it.
The lesson: your config is attack surface too
It is tempting to think of CVEs as living in application code, with the proxy as a trusted, static layer. This bug is a corrective. The configuration you wrote (the specific regex in your rewrite rules) is part of the reachable attack surface, and a vendor bug in how that config is processed can be triggered by an ordinary unauthenticated request. Edge software earns its “boring and reliable” reputation precisely because bugs in it are rare and loud; when one lands in the most-used directive, it deserves prompt attention rather than the patch-it-next-quarter treatment a frontend dependency might get.
There is a second-order reason this class is easy to under-prioritize: the trigger condition is specific enough that many operators will glance at the advisory, decide “we probably do not do that,” and move on without checking. But “overlapping captures referenced more than once” is not an exotic pattern: it is what you get when someone wraps an alternation in an extra group, or copies a rewrite rule from a forum answer, or builds a redirect that stitches together two captured path segments. The only way to know whether your configuration matches the dangerous shape is to actually grep your rewrite rules, not to reason about whether you “usually” write them that way. Assumption is how a fixable exposure becomes a standing one. Treat the advisory as a prompt to inventory, not a prompt to guess.
It is also a reminder that regular expressions in security-relevant positions (rewrite rules, WAF patterns, validation filters) deserve the same review discipline as code, because they are code. A regex that looks correct can carry subtle behavior around captures, anchoring, and backtracking that only matters under adversarial input. The rewrite block is one of the few places where a single line of configuration is directly exposed to every unauthenticated visitor on the internet.
The defensible check
You confirm exposure two ways (by version and by config shape) neither of which involves attacking a live edge:
# CVE-2026-9256: version + config-pattern check (no exploitation).
nginx -v 2>&1 # compare build against the fixed release in the advisory
# Surface rewrite rules that match the dangerous shape: nested captures + multi-ref replacement.
grep -rnE 'rewrite\s+[^;]*\(\([^)]*\)\)[^;]*\$[0-9]\$[0-9]' /etc/nginx/
grep -rnE 'return\s+30[0-9][^;]*\$[0-9]\$[0-9]' /etc/nginx/
# FINDING = a pre-fix NGINX build AND a rewrite/return using overlapping captures
# with a multi-capture replacement in a redirect/args context. A patched build,
# or configs without the nested-capture-plus-multi-ref pattern, is a PASS.
The fix
- Upgrade NGINX to the fixed release named in the advisory. This is the real fix and it is low-risk for a proxy.
- Simplify the regex as defense-in-depth. Where a rewrite uses
((.*))-style nested captures, collapse to a single capture and a single reference if the rule's intent allows. Fewer overlapping groups, fewer ways to hit the bug. - Inventory your rewrite rules. Most operators do not know how many redirect rules they run or what shapes they use. This is a good prompt to audit the rewrite block across every vhost.
How Celvex Sentry tests for this
Our continuous-monitoring suite fingerprints edge-proxy builds and, where configuration is in scope for an engagement, flags rewrite rules matching the vulnerable overlapping-capture shape. The finding requires a pre-fix build together with a config that can actually trigger the flaw. A patched proxy or a rule that does not match the pattern is a PASS, not noise. When both hold, we mint a Proof Capsule with the version evidence, the matching rule, and the upgrade-and-simplify remediation attached.
Sources
Get your exposure check: full report in 4-24 hours
Real assessment on production-grade infrastructure. We prove what is exploitable and attach the fix. Paying customers get priority capacity.
Queue My Assessment