nginx rewrite module heap corruption from escaped captures

nginx rewrite module heap corruption from escaped captures

Escaped capture data can turn a rewrite rule into a heap write when the length pass and the copy pass stop agreeing. In the affected path, ngx_http_script_copy_capture_code() can size a buffer for one version of the data and then write a longer escaped version into it. The result is heap corruption, worker crashes, and in the worst case a path towards remote code execution.

How escaped capture data turns a rewrite into a heap write

The trigger is a crafted URI that reaches the rewrite module with capture groups containing escapable characters. The rewrite engine first calculates how much space the copied capture needs, then copies the data into the allocated buffer. If the state used for that calculation is stale, the estimate is wrong and the write can overrun the heap buffer.

That is the ugly part of nginx rewrite module heap corruption: the failure happens inside normal rewrite processing, not in some exotic corner of the request pipeline. A rule that looks harmless on paper can become dangerous when it mixes captured input with escaping behaviour that changes between the sizing pass and the copy pass.

Heap corruption is the practical outcome. A crash is the common one. A controlled heap spray is the more uncomfortable one.

The length pass and copy pass stop agreeing in ngx_http_script_copy_capture_code()

ngx_http_script_copy_capture_code() sits at the centre of the bug. The function handles capture copying for rewrite scripts, and the bad state means the length calculation no longer matches the data written later. If the copied capture expands after escaping, the buffer size is no longer enough.

That mismatch is enough on its own. Once the copy pass writes beyond the allocated area, adjacent heap memory gets corrupted. With the right request pattern, repeated allocations and frees can make the heap layout easier to abuse. That is where exploitation attempts start to look like heap spray activity rather than a simple crash.

Rewrite directives that mix ? with set or if open the door

The risky pattern is rewrite directives that include ? in the replacement string and then feed captured values into set or if. That combination gives the rewrite module more moving parts while it is still carrying capture state. If the capture data includes escapable characters, the stale state can surface at the worst point.

This is not every rewrite rule with captures. It is the ones that combine query string handling with conditional logic and captured data in the same path. Those are the ones worth treating as suspect until the build is confirmed and the edge layer is blocking obvious exploitation attempts.

Hardening nginx before CVE-2026-42945 bites

nginx 1.30.1 is the clean boundary here. Older builds should be treated as exposed if they carry the affected rewrite module code path. Verify the binary in use, not the package name in a repo entry, because drift between what was installed and what is actually running is a classic way to lie to yourself.

Upgrade to nginx 1.30.1 or later and confirm the build in use

Upgrade to nginx 1.30.1 or later. Then check the running worker process, not just the config management output. A version string in a changelog means little if the old binary is still on disk and still serving traffic.

If a reverse proxy or container image is involved, confirm the image tag and the deployed artefact. Rebuilds and restarts fail in the most boring way possible, which is usually the way these things slip through.

Block exploit patterns at the edge and watch for worker crashes

Edge filtering buys time, not immunity. Cloudflare pushed emergency WAF rules for exploitation attempts against CVE-2026-42945, which tells you what the traffic looks like when someone starts testing this in anger. A WAF block does not fix the heap bug, but it can cut off obvious probes before they reach nginx.

Watch for worker process crashes, restart loops, and any surge in requests that target rewrite-heavy routes with odd capture content. If the service starts dying under a narrow set of URIs, do not assume it is random bad luck. That pattern is often the first visible sign that the rewrite module is being poked where it hurts.

Related posts

Agentic AI still needs domain judgement

Agentic AI can write the thing, but it still cannot tell you whether the thing is right. That is where domain expertise matters, because a clean config or neat bit of glue logic can still be wrong in...

Weekly Tech Digest | 06 Jul 2026

Stay updated with the latest in tech! This digest covers AI ethics, auto industry shifts, and the impact of politics on technology, exploring today's pressing issues.

wolfCOSE zero-allocation parsing in embedded C

wolfCOSE looks sensible only if you care about what your firmware actually has to carry. I like that, because on small targets the wrong crypto feature can cost more than the message itself, and there...