18-Year-Old RCE in Nginx (CVE-2026-42945)

On May 13, a vulnerability was fixed in the widely used web server nginx for high-load systems: CVE-2026-42945, which could potentially lead to RCE. The vulnerability has existed for 18 years (since 2008) in version 0.6.27.

To exploit it, a specific combination of directives must be defined in the server config, not necessarily present everywhere, but sometimes applicable, such as:
rewrite ^(.*) /new?c=1;
set $myvar $1;
return 200 $myvar;

Key details:

  • the rewrite directive comes first, where (the first argument) a regular expression with a captured parameter (something in parentheses) is replaced by (the second argument) a path containing a question mark;
  • the set directive (the second rewrite or if could also work here) uses the captured parameter from the rewritten path (in this case, $1).

The vulnerability works as follows:

  • the first rewrite directive, on encountering a question mark, sets an internal flag is_args, meaning "now we are collecting GET parameters for the rewritten URL, everything needs to be escaped," and (this is the crux of the bug) forgets to reset this flag at the end of its operation;
  • the subsequent set directive, while forming the value for $myvar, mistakenly applies the previously set is_args, and writes the escaped value of the captured parameter $1 into my_var; the problem is that the buffer for $myvar is allocated earlier, before substitutions are executed, and its length is calculated with is_args=0, meaning the escaped value turns out to be longer than the allocated buffer, causing a write to occur outside the allocated buffer into other server data structures. For this to happen, it is enough to send a request with characters that need escaping, such as plus signs, at the position where the regular expression parameter is captured.

If there is no ALSR on the host, this vulnerability can be exploited for remote code execution with the privileges of the nginx worker process, there is PoC (not a pure exploit, demonstration in the sandbox).

The vulnerability has been fixed in the stable branch nginx 1.30.1, and in the new development version 1.31.0. link to the commit.

Notably, a similar error was already fixed 14 years ago (in 2012) in another location nearby.

——-

The F5 website has a recommendation for temporarily mitigating the vulnerability in case updating the nginx version quickly is not possible — it is necessary to replace unnamed arguments with named ones, and in this case, they state that the vulnerability will not manifest. Here's an example from there:
was: rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;
became: rewrite ^/users/(?[0-9]+)/profile/(?

.*)$ /profile.php?id=$user_id&tab=$section last;

Information about the vulnerability was provided by Zhenpeng (Leo) Lin from DepthFirst. Additionally, he reported the following issues that have also been fixed:

  • CVE-2026-40701 (the commit) use-after-free when using ssl_verify_client+ssl_ocsp (apparently without RCE)
  • CVE-2026-42934 (the commit) out-of-bounds reading in the utf-8 parser under specific circumstances, which may lead to minor data leaks or crash the worker process
  • CVE-2026-42946 (the commit) excessive memory allocation and out-of-bounds reading when using scgi/uwsgi modules, this issue manifests when there is a malicious backend (upstream) via the specified protocols, or during a man-in-the-middle communication channel with the backend, potentially leading to reading nginx memory or crashing the worker process

Source: linux.org.ru

Buy reliable website hosting with DDoS protection, VPS VDS servers 🔥 Buy reliable website hosting with DDoS protection, VPS VDS servers | ProHoster