We took the new 18-year-old nginx vulnerability (named NGINX Rift, CVE-2026-42945), wrote a static scanner for its vulnerable pattern, and pointed it at the most-deployed nginx configs on GitHub.
The TL;DR is the boring one. We pulled 1,465 unique configs from 528 popular (≥25⭐) repos, scanned every single one, and got zero hits for vulnerable configs.
Zero across GitLab, Mastodon, Discourse, n8n, Coolify, Sentry, Grafana, MinIO, NocoDB, Bitwarden, the certbot test fixtures, h5bp's reference configs, the nginxinc reference configs, the whole linuxserver.io image fleet, and Bitnami's nginx-based stacks. Nothing.
We did get one hit, but it wasn't in a popular repo. It was a tiny side project with no stars. Not anyone's production.
The interesting question is why.
The shape of the bug
The vulnerable pattern is narrow and specific:
location ~ ^/api/(.*)$ {
rewrite ^/api/(.*)$ /internal?migrated=true;
set $original_endpoint $1;
}Two ingredients, both in the same location block:
A
rewritewhose replacement contains?(which sets nginx's internalis_argsflag).A
set $var $Nthat pulls a regex capture from the same location.
nginx's script engine runs in two passes, a length-calculation pass and a copy pass. The is_args flag is set differently between them. On the copy pass, capture-group bytes get URL-escaped (a single + becomes three bytes, %2B), but the buffer was sized on the unescaped length. Capture-controlled bytes spill out of the heap allocation, you overwrite a ngx_pool_cleanup_t, get a function pointer onto the stack, and you have RCE.
It was introduced in nginx 0.6.27 back in 2008 and survived all the way through 1.30.0. Every NGINX Plus from R32 to R36 and the Ingress Controller through 5.4.1 are affected.
What we actually found
We collected nginx configs from 528 popular GitHub repos (≥25⭐), 1,465 unique by content hash, across three pipelines.
Global code search. 147 configs from production-tuning queries against the GitHub code index.
Curated git-tree harvest. 227 configs from about 100 hand-picked self-hosted projects (GitLab, Mastodon, Discourse, and so on), using the tree API to bypass the broken legacy code search.
Wide-net tree harvest. 1,090 configs from another 1,200ish repos pulled from awesome-selfhosted, the linuxserver/ and nginxinc/ orgs, Bitnami's image library, and every nginx-named repo with ≥200 stars.
We had 0 hits for vulnerable configs across those files.
Why the in-the-wild rate is so low
Each ingredient is common on its own.
rewrite ... /path?foo=baris everywhere. Every redirect to a query-string endpoint uses it.set $x $1is everywhere. Pulling a regex capture out of a URL is standard.
But putting them together is unusual. If you're rewriting the URL, the captures from the original location pattern are typically used in the rewrite target itself, not stashed separately with set. People who want the capture for later (logging, an upstream header) tend to either skip the rewrite entirely and pass $1 to proxy_pass, or rewrite without a query string. The combo the bug needs is a niche overlap of two common patterns.
Where the real attack surface is
The 1,465 configs we scanned are static files committed to repos. That's not the whole picture. The risk concentrates somewhere else.
NGINX Ingress Controllers. Templates generate configs from Kubernetes resources. We audited both dominant controllers line by line and scanned their rendered output. Both clean by default. The community controller's
rewrite-targetvalidator rejects?; the F5 controller never emits asetreferencing a capture group next to its rewrites. The only injection path is the*-snippetannotation, off by default since v1.9 (CVE-2021-25742).WAF and edge products built on nginx. Same templating risk, higher blast radius, because they sit at the edge.
Multi-tenant hosting platforms. Anyone who lets users contribute URL-rewrite rules through a UI.
Static-file scanning of popular self-hosted apps is the easy data to get. The hard data, the actual exposure, lives in rendered configs on running machines.
What to do
Upgrade. nginx 1.30.1+, NGINX Plus R37, Ingress Controller 5.4.2.
If you template nginx configs, audit the rendered output, not just the templates. The pattern is straightforward to grep for: a
locationblock containing both arewritewhose replacement has a?in it, and aset $var $Nreferencing a regex capture from the same location.Audit anywhere users can influence rewrite rules. Ingress annotations, platform config UIs, anything that pipes user input into a generated nginx config.
