Researchers found a critical 18-year-old buffer overflow flaw in NGINX, tracked as CVE-2026-42945 and named NGINX Rift.
If you run NGINX, and statistically speaking, there is a very good chance you do, this week brought news worth stopping for.
Security researchers at depthfirst disclosed a critical heap buffer overflow vulnerability in both NGINX Plus and NGINX Open Source that has been sitting undetected in the codebase for eighteen years. The flaw, tracked as CVE-2026-42945 and assigned a CVSS v4 score of 9.2, carries the name NGINX Rift, and its implications extend well beyond a routine patch cycle.
NGINX powers a substantial share of the public internet, reverse proxies, load balancers, ingress controllers, application delivery platforms, making the attack surface here unusually broad. The vulnerability lives in ngx_http_rewrite_module, a component included in every standard NGINX build, and the trigger is a configuration pattern common enough that a significant portion of real-world deployments may be affected without anyone knowing it.
The root of the problem lies in how NGINX handles rewrite directives that combine unnamed PCRE capture groups, the familiar $1, $2 syntax, with a replacement string containing a question mark, when followed by another rewrite, if, or set directive in the same scope.
The mechanics are subtle, but the outcome is not. When a question mark appears in the replacement, an internal flag on the script engine is set and never cleared. A subsequent length calculation uses a fresh sub-engine that does not account for URI escaping, producing a buffer sized for raw bytes. The actual write, however, runs on the original engine where the escaping flag is still active, and characters like +, %, and & each expand by two bytes during the copy. The result is a write that runs deterministically past the end of the allocated buffer, a heap overflow controlled in shape by the contents of the attacker’s URI.
“When that pattern is present, NGINX computes the destination buffer using one set of escaping assumptions and then writes to it using another. The write runs past the allocated buffer, producing deterministic memory corruption.” reads the report published by depthfirst. “Any NGINX deployment running an affected version with that pattern is exposed until it is patched or reconfigured.”
That last detail matters. Unlike many memory corruption bugs where the overflow is influenced by unpredictable internal state, the bytes written beyond the allocation here are derived directly from the attacker’s request. The corruption is shaped, not random, which significantly improves the reliability of exploitation.
“An attacker who can reach a vulnerable NGINX server over HTTP can send a single request that overflows the heap in the worker process and achieves remote code execution.” continues the report. “There is no authentication step, no prior access requirement, and no need for an existing session.”
On systems with ASLR disabled, a configuration still found in some production environments, remote code execution in the NGINX worker process is achievable with a single crafted HTTP request. Even where ASLR is enabled, repeated requests can be used to drive workers into a crash loop, degrading availability across every application served by that instance.
“The bytes written past the allocation are derived from the attacker’s URI, so the corruption is shaped by the attacker rather than random.” states depthfirst. “Repeated requests can also be used to keep workers in a crash loop and degrade availability for every site served by the instance.”
The vulnerability affects a wide range of F5 and NGINX products. NGINX Open Source versions from 0.6.27 through 1.30.0 are affected, as are NGINX Plus R32 through R36. The issue also extends to NGINX Instance Manager (2.16.0–2.21.1), F5 WAF for NGINX (5.9.0–5.12.1), NGINX App Protect WAF (4.9.0–4.16.0 and 5.1.0–5.8.0), F5 DoS for NGINX (4.8.0), NGINX App Protect DoS (4.3.0–4.7.0), NGINX Gateway Fabric (1.3.0–1.6.2 and 2.0.0–2.5.1), and NGINX Ingress Controller (3.5.0–3.7.2, 4.0.0–4.0.1, and 5.0.0–5.4.1). Products such as BIG-IP, F5OS, and F5 Distributed Cloud are not affected.
Fixed versions were released following responsible disclosure on April 21, 2026. NGINX Open Source users should move to 1.30.1 or 1.31.0. NGINX Plus R36 users should apply R36 P4, while R32 users should apply R32 P6. Fixes for Instance Manager, App Protect, Gateway Fabric, and Ingress Controller are available in updated release branches.
The Rift disclosure was accompanied by patches for three further vulnerabilities in NGINX Plus and NGINX Open Source:
- CVE-2026-42946 (CVSS v4 8.3) — An excessive memory allocation flaw in the ngx_http_scgi_module and ngx_http_uwsgi_module modules. An adversary-in-the-middle attacker capable of controlling upstream server responses could read memory from the NGINX worker process or force a restart when scgi_pass or uwsgi_pass directives are in use.
- CVE-2026-40701 (CVSS v4 6.3) — A use-after-free in ngx_http_ssl_module that can be triggered by a remote unauthenticated attacker when ssl_verify_client is configured as “on” or “optional” and ssl_ocsp is enabled, potentially allowing limited data modification or worker restart.
- CVE-2026-42934 (CVSS v4 6.3) — An out-of-bounds read in ngx_http_charset_module that can expose memory contents or cause a worker restart when charset, source_charset, charset_map, and proxy_pass with disabled buffering are all configured together.
The recommended action is straightforward: upgrade. Restart NGINX after installing the fixed release so that workers reload the patched binary.
For environments where an immediate upgrade is not feasible, a configuration-level workaround exists specifically for CVE-2026-42945. The vulnerability is only triggerable when unnamed PCRE captures are combined with question marks in replacement strings. Replacing unnamed captures ($1, $2) with named captures eliminates the vulnerable code path without requiring downtime.
A vulnerable configuration like rewrite ^/users/([0-9]+)$ /profile.php?id=$1 last; becomes safe when rewritten as rewrite ^/users/(?<user_id>[0-9]+)$ /profile.php?id=$user_id last;. It is a small change with meaningful protective value while patching is arranged.
There are no reports of this vulnerability being exploited in the wild at the time of disclosure, and depthfirst coordinated the release with F5 to ensure fixes were available alongside the public advisory. That window will not stay open indefinitely.
Follow me on Twitter: @securityaffairs and Facebook and Mastodon
(SecurityAffairs – hacking, NGINX Rift)
