CVE-2026-42945: Technical Analysis of the NGINX Rift Heap Buffer Overflow
CVE-2026-42945, codenamed "NGINX Rift," identifies a critical heap-based buffer overflow vulnerability within the NGINX ngx_http_rewrite_module. Disclosed in May 2026 by researchers at depthfirst, the flaw stems from a fundamental logic error in how NGINX's internal script engine manages memory allocation during URI rewriting. The vulnerability has persisted in the NGINX codebase for approximately eighteen years, dating back to version 0.6.27 released in 2008. It allows an unauthenticated remote attacker to achieve code execution or cause a worker process crash by sending a single, specifically crafted HTTP request that triggers an inconsistent state in the script engine's two-pass processing logic.
Root Cause Analysis: The Internal Script Engine Logic
The core of the issue resides in the ngx_http_script_run function and the associated complex value execution logic. NGINX processes rewrite, set, and if directives using a virtual machine-like script engine. This engine typically operates in two distinct passes to ensure memory safety: a length calculation pass and a data copy pass. During the first pass, the engine traverses the script components to determine the exact number of bytes required for the destination buffer. In the second pass, it allocates the memory and performs the actual string manipulation and copying.
The "Rift" vulnerability occurs when a rewrite directive is configured with unnamed Perl-Compatible Regular Expression (PCRE) captures (e.g., $1, $2) and a replacement string containing a literal question mark (?). When the script engine encounters a question mark in a replacement string, it invokes ngx_http_script_start_args_code, which sets an internal flag, e->is_args = 1, on the main script engine state. This flag signals that subsequent data should be treated as part of the query string and may require URI escaping.
The failure mechanism is triggered because this is_args flag is never reset between the evaluation of subsequent script codes within the same request context. When a subsequent set, if, or rewrite directive is executed, it inherits this stale state. Specifically, the length calculation pass for the second directive may use a freshly initialized sub-engine that does not account for the is_args flag, resulting in an undersized buffer allocation. However, the data copy pass—still operating on the primary engine state where is_args is set—applies URI escaping to the capture group data. This escaping expands characters (e.g., a space becomes %20), causing the write operation to exceed the boundaries of the heap buffer.
// Conceptual representation of the logic failure in ngx_http_script_complex_value_code
// Pass 1: Length Calculation
len = 0;
for (i = 0; i < script->lengths->nelts; i++) {
lcode = script->lengths->elts[i];
len += lcode(e); // Underestimates if e->is_args is inconsistent
}
e->buf = ngx_palloc(e->pool, len); // Allocation based on underestimate
// Pass 2: Data Copy
for (i = 0; i < script->values->nelts; i++) {
vcode = script->values->elts[i];
e->pos = vcode(e); // Overwrites if e->is_args triggers escaping expansion
}
Trigger Pattern and Vulnerable Configurations
The vulnerability is highly deterministic and depends on specific configuration patterns. The most common trigger involves a chain of directives where the first directive sets the global script engine state and the second directive performs the overflow. Organizations can identify potentially vulnerable configurations by auditing their nginx.conf files for the following sequence:
- A
rewritedirective using unnamed captures ($1,$2, etc.). - A replacement string in that
rewritethat includes a?. - A subsequent
rewrite,set, orifdirective that references a capture group.
The following example demonstrates a vulnerable configuration block:
location /vulnerable/ {
# Directive 1: Sets e->is_args = 1 and uses unnamed captures
rewrite ^/vulnerable/(.*)$ /internal.php?id=$1 last;
# Directive 2: Inherits stale state; overflow occurs during variable expansion
set $my_var "user:$1";
}
In this scenario, if an attacker provides a URI like /vulnerable/%20%20%20, the escaping logic in the second pass may write significantly more data than the initial length calculation anticipated, leading to a heap corruption. To identify these legacy patterns across large-scale infrastructure, security teams often utilize Secably for automated vulnerability scanning and configuration auditing, which can flag NGINX instances running versions or configurations susceptible to this specific memory corruption flaw.
Affected Versions and Patch Information
The vulnerability impacts a vast range of NGINX versions due to its longevity in the source code. While many older versions are technically vulnerable, F5 has officially provided patches for supported branches. Versions that have reached End of Technical Support (EoTS) remain unpatched and should be migrated immediately.
| Product | Vulnerable Versions | Fixed Versions |
|---|---|---|
| NGINX Open Source (Mainline) | 1.0.0 - 1.30.0 | 1.31.0 |
| NGINX Open Source (Stable) | 1.0.0 - 1.29.x | 1.30.1 |
| NGINX Plus | R32 - R36 | R32 P6, R36 P4 |
| NGINX Ingress Controller | 3.5.0 - 5.4.1 | Refer to F5 K000161019 |
| Legacy NGINX | 0.6.27 - 0.9.7 | None (End of Life) |
Because NGINX often sits at the edge of the network, many exposed instances may not be immediately known to centralized IT teams. Researchers and defenders can use Zondex to perform internet-wide discovery of NGINX banners and service versions to map the attack surface and prioritize remediation for external-facing assets that match the vulnerable version ranges.
Exploitation Vector: Heap Feng Shui and RCE
Exploiting CVE-2026-42945 for Remote Code Execution (RCE) requires bypassing modern memory protections such as Address Space Layout Randomization (ASLR). However, NGINX's architecture simplifies certain aspects of this process. NGINX utilizes a master-worker process model where the master process forks child workers. Since fork() duplicates the memory space, all worker processes share the same ASLR base addresses until the master process itself is restarted. An attacker can repeatedly crash a worker process to probe the memory layout, as the master will simply respawn a new worker with an identical memory map.
The technical exploitation path demonstrated in the "Rift" proof-of-concept involves "Cross-Request Heap Feng Shui." By sending multiple requests, an attacker can influence the heap layout of the worker process, placing a target object—such as a ngx_pool_cleanup_t structure—adjacent to the vulnerable buffer. The heap overflow is then used to overwrite the cleanup handler's function pointer with the address of a gadget or a system call (e.g., system()). When the request finishes and the pool is cleaned up, the hijacked pointer is executed, leading to shell command execution under the context of the NGINX worker user (usually www-data or nginx).
Detection and Mitigation Strategies
The most effective mitigation is an immediate upgrade to NGINX 1.31.0 or 1.30.1. If patching is not feasible due to legacy constraints or complex dependencies, the vulnerability can be mitigated at the configuration level by replacing all unnamed PCRE captures with named captures. Named captures do not rely on the same internal script engine capture logic that triggers the is_args inconsistency.
Vulnerable Pattern:
rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;
Mitigated Pattern:
rewrite ^/users/(?<user_id>[0-9]+)/profile/(?<section>.*)$ /profile.php?id=$user_id&tab=$section last;
In addition to configuration changes, defenders should monitor for unusual worker process restarts. NGINX logs worker process terminations; a high frequency of SIGSEGV or SIGABRT signals in the error logs can indicate active exploitation attempts or automated fuzzing targeting this vulnerability. Since the overflow is triggered by URI expansion, Web Application Firewalls (WAF) can be tuned to detect excessively long or highly encoded URIs targeting endpoints known to use complex rewrite rules. However, because the overflow is deterministic and can be triggered with relatively small payloads depending on the heap state, signature-based detection may be unreliable without deep inspection of the specific rewrite logic implemented in the backend configuration.