TL;DR

When a critical nginx vulnerability hits the headlines, security teams patch nginx. But what if the same vulnerable code is running somewhere they’re not looking?

While the rest of the industry was busy patching nginx, Orca’s Threat Research Team was asking a different question and the answer led us straight to Tengine

Tengine, Alibaba’s nginx fork, is deployed on 1.45 million internet-facing servers worldwide and carries the exact same vulnerable code behind CVE-2026-42945 and CVE-2026-9256. These CVEs are two heap buffer overflows that let an unauthenticated attacker crash a Tengine worker process with a single crafted HTTP request. 

These vulnerabilities were untouched, unpatched, and almost completely unmonitored for nearly two decades. We’re talking CDN edges, reverse proxies, and the Aliyun and Taobao infrastructure that fronts an enormous chunk of the internet. So we did the work to confirm it: compiled Tengine from source, built working exploits for both CVEs, and watched worker processes crash on demand with full ASAN stack traces. When Orca began this research, no patch, no commit, and no acknowledgement of these vulnerabilities from Tengine’s maintainers existed. 

As of June 10, 2026, both CVEs have been fixed in the main branch, with a patched release (Tengine 3.2.0) targeted for June 30, 2026. Recommended mitigation steps are included at the end of this blog.

Background

The two CVEs we started with are both heap buffer overflows in nginx’s rewrite engine, same source file (ngx_http_script.c), same function family, two different bugs.

CVE-2026-42945 (“NGINX Rift”) 

  • CVSS (v4): 9.2
  • A stale is_args flag leaks between chained rewrite rules, causing the length-calculation pass and the write pass to disagree about buffer size. Fixed in nginx 1.30.1 / 1.31.0 on May 13, 2026.

CVE-2026-9256 (“nginx-poolslip”) 

  • CVSS (v4): 9.2
  • Overlapping PCRE captures cause URI-escape overhead to be counted once during sizing but written twice. Fixed in nginx 1.30.2 / 1.31.1 on May 22, 2026 and upgrading to 1.30.1 to patch the first CVE leaves you exposed to the second.

Eighteen years in the wild. Both unauthenticated. Both triggered by a single crafted HTTP request. F5 patched nginx and the industry moved on.

But these bugs don’t belong to nginx. They belong to a file. Any project that carries ngx_http_script.c carries the vulnerability. So we started asking: who else ships this code?

The Vulnerable Code

We pulled Tengine 3.1.0 from source. It’s based on nginx 1.24.0 – well behind the patched versions and carrying both bugs untouched in two functions in ngx_http_script.c: ngx_http_script_regex_start_code() (CVE-2026-9256) and ngx_http_script_regex_end_code() (CVE-2026-42945).

CVE-2026-9256: Double-Counting with Overlapping Captures

The size-calculation pass in ngx_http_script_regex_start_code() accounts for URI-escape overhead exactly once – across the entire URI:

if (code->uri) {
    if (r->ncaptures && (r->quoted_uri || r->plus_in_uri)) {
        e->buf.len += 2 * ngx_escape_uri(NULL, r->uri.data, r->uri.len,
                                         NGX_ESCAPE_ARGS);
    }
}
for (n = 2; n < r->ncaptures; n += 2) {
    e->buf.len += r->captures[n + 1] - r->captures[n];  // raw size, no escaping
}

But the write pass (ngx_http_script_copy_capture_code) escapes each capture independently. With overlapping captures like ((.+)), $1 and $2 point to the same bytes – so the write pass escapes them twice, while the buffer was only sized for once. A URI with 900 + characters (each + expands to 3-byte %2B) blows past the allocation:

PhaseSize
Allocated (length pass)4,304 bytes
Written (write pass)~6,104 bytes
Overflow~1,800 bytes

CVE-2026-42945: Stale is_args Flag

In ngx_http_script_regex_end_code, the e->is_args flag never reset between chained rewrite rules:

// Tengine 3.1.0 — missing: e->is_args = 0;
e->quote = 0;

When the first rewrite rule’s replacement string contains a ? (setting is_args = 1), the flag carries over into the next rule. The length engine runs with a fresh le.is_args = 0, but the write engine uses the stale e->is_args = 1 – so the write phase escapes characters the length phase didn’t account for, and the buffer overflows. In our test, a chained-rewrite request carrying 3,200 ‘A’ characters followed by 900 ‘+’ characters drove the write past the 4,124-byte buffer (ASAN trace below).

Proof: ASAN-Confirmed Crashes

Source inheritance isn’t proof. To confirm both bugs were actually exploitable in Tengine 3.1.0 not just present in the code we built a controlled test environment and ran the attacks end-to-end. Tengine 3.1.0 compiled from source with AddressSanitizer (-fsanitize=address) in a Docker container. Three test cases: one control to prove the bug doesn’t fire on benign input, two exploits for the two CVEs.

Test Configuration

server {
    listen 8081;

    # SAFE: single capture (control test)
    location /safe/ {
        rewrite ^/safe/(.+)$ /out/$1 redirect;
    }

    # CVE-2026-9256: overlapping captures
    location /vuln/ {
        rewrite ^/vuln/((.+))$ /out/$1/$2 redirect;
    }

    # CVE-2026-42945: is_args carry-over
    location /rift/ {
        rewrite ^/rift/(.+)$  /step2/$1?injected;
        rewrite ^/step2/(.+)$ /out/$host/$1;
        return 404;
    }
}

Results

Control (/safe/, single capture, 900 + chars):

  • The worker survived. No ASAN output, clean 302 redirect. This is the important negative result  it proves the bug isn’t a generic regex-rewrite issue. It requires the specific overlapping-captures or chained-rewrite pattern.

CVE-2026-9256 (/vuln/, overlapping captures, 900 + chars):

  • Worker crashed. PID changed from 7 to 47 (master respawned a fresh worker).
  • ASAN output:
==7==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xffff9ba205d0
WRITE of size 1 at 0xffff9ba205d0 thread T0
    #0 ngx_escape_uri              src/core/ngx_string.c:1689
    #1 ngx_http_script_copy_capture_code  src/http/ngx_http_script.c:1399
    #2 ngx_http_rewrite_handler    src/http/modules/ngx_http_rewrite_module.c:180

0xffff9ba205d0 is located 0 bytes to the right of 4304-byte region

CVE-2026-42945 (/rift/, chained rewrites, 3200 A + 900 + chars):

  • Worker crashed. PID changed from 47 to 102.
  • ASAN output:
==47==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xffff9ba1c91c
WRITE of size 1 at 0xffff9ba1c91c thread T0
    #0 ngx_escape_uri              src/core/ngx_string.c:1689
    #1 ngx_http_script_copy_capture_code  src/http/ngx_http_script.c:1399
    #2 ngx_http_rewrite_handler    src/http/modules/ngx_http_rewrite_module.c:180

0xffff9ba1c91c is located 0 bytes to the right of 4124-byte region

Same crash site, two different triggers. Both stack traces land in ngx_http_script_copy_capture_code, not the functions named above – exactly as expected: regex_start_code/_end_code compute the under-sized buffer, while the out-of-bounds write happens later, when copy_capture_code escapes the captures into it. Both bugs confirmed exploitable in Tengine with a single unauthenticated HTTP request.

Internet Exposure: 1.45 Million Servers

Using Shodan, we queried for internet-facing Tengine servers. The results:

Total internet-facing Tengine servers: 1,453,152

A large number of the Tengine servers are in China, where it is deeply embedded in Alibaba Cloud deployments, Taobao, Tmall, and Aliyun managed services. Many operate as CDN edge nodes or reverse proxies, where a single worker crash cascades to hundreds of downstream services.

Tengine – the Alibaba-maintained, high-scale-proven fork – is now the liability. Operators chose it for its pedigree, and that same pedigree went 2.5 years without a single release. Today, every available version of Tengine is vulnerable.

Impact

Denial of Service

An unauthenticated attacker can crash a Tengine worker process with a single HTTP request containing + characters in the URL path. No login, no special headers, no cookies – just a crafted URL.

  • In single-worker or master_process off deployments: one request takes the server offline completely.
  • In multi-worker deployments: sending the payload in a loop kills workers faster than the master process can respawn them, resulting in sustained denial of service.

Beyond DoS: Potential for Code Execution

Both bugs are heap buffer overflows – rarely “just” a crash. The upstream CVE-2026-42945 advisory notes that where ASLR is disabled or bypassed, the corruption may be steerable toward code execution.

Preconditions

Exploitation requires:

  • CVE-2026-9256: The rewrite directive uses a regex pattern with distinct, overlapping PCRE captures (e.g., ^/((.*))$) and a replacement string that references multiple such captures (e.g., $1$2) in a redirect or arguments context.
  • CVE-2026-42945: The rewrite directive is followed by a rewrite, if, or set directive and an unnamed PCRE capture ($1, $2) with a replacement string that includes a question mark (?).

These are standard, documented nginx patterns. They appear in production configurations and nothing about them signals danger to an operator.

Recommendations and Mitigations

At the time of writing, the vulnerabilities discussed in this blog have been patched in Tengine’s GitHub repository but have not yet been included in an official release. We recommend that organizations running Tengine assess their exposure and consider the following steps: 

  • If you are building Tengine from source, update to the latest commit on the master branch which includes the fixes. 
  • If you are running a released version, consider applying the relevant patches manually or switching to an upstream Nginx build until a new Tengine release is available. 

Tengine’s last release (3.1.0) was released on October 27, 2023. During the course of our investigation, individual commits addressing both CVEs appeared on Tengine’s GitHub master branch, followed by a public discussion announcing a planned 3.2.0 release targeting June 30, 2026, which will upgrade the nginx core from 1.24.0 to 1.31.x and backport the security fixes. But until that release ships, the official Tengine website, every package manager, and every tagged release still serves the vulnerable 3.1.0. Anyone who downloads and builds Tengine today gets both CVEs out of the box. No patched version has ever been released, so every Tengine server in the world is running the unpatched binary and any using the affected rewrite patterns is exploitable with a single unauthenticated request.

Looking Beyond the Obvious

This research started with a question nobody else was asking. When CVE-2026-42945 and CVE-2026-9256 hit, the industry did the obvious thing: patch nginx, move on. Our Threat Research Team didn’t stop at the headline. We asked the quieter, harder question – who else is running this exact code, and isn’t being told to patch? That single question led us from a patched upstream project to 1.45 million exposed servers running a fork nobody was watching.

That’s the discipline behind everything we do: we don’t just track CVEs, we track code. A vulnerability doesn’t live in a product name – it lives in a file, and that file travels into forks, vendored copies, and abandoned projects long after the original is fixed. Looking beyond the obvious target is how blind spots like Tengine get found before an attacker finds them first. The next inherited flaw is already out there, sitting in code that ships under a different name. We’ll keep looking where others stop.

How Can Orca Help?

Orca enables customers to quickly identify every Tengine instance across their cloud environments, understand exposure in context—including internet accessibility, runtime reachability, and asset criticality—and prioritize remediation based on real risk. Orca’s platform builds a full software inventory from runtime block storage, detecting Tengine builds that carry the vulnerable code even when traditional scanners overlook them. Security teams can use Orca to pinpoint which CDN edges, reverse proxies, and production deployments run Tengine, then focus remediation on the most critical, internet-facing assets first. 

Orca Security platform vulnerability window showing details for the nginx-poolslip vulnerability (CVE-2026-9256) affecting NGINX rewrite modules with an 8.1 CVSS score.
Orca detecting CVE-2026-9256 in Tengine, Alibaba’s for of NGINX
Orca Security platform vulnerability window showing details for CVE-2026-42945 affecting NGINX rewrite modules with an 8.1 CVSS score.
Orca detecting CVE-2026-42945 in Tengine

The Tengine story is not unique. Across cloud environments, organizations unknowingly run software forks, outdated dependencies, and abandoned projects that carry inherited vulnerabilities with no patches in sight. Orca’s full-stack approach ensures that these hidden risks don’t stay hidden – and that your team is never the last to know.