A few bytes spill onto the next heap chunk
Technical writeup of CVE-2026-42945, the NGINX rewrite module heap overflow, plus what it means for LLM deployments sitting behind the proxy.
What the bug is
CVE-2026-42945 is a heap buffer overflow in the NGINX rewrite module, the component that handles directives like rewrite, if, and the regex captures inside location blocks. The flaw lives in how the module sizes the buffer used to hold the rewritten URI after variable interpolation. When a request contains a long, attacker-controlled value that gets pulled into a captured group and then re-emitted into the rewrite target, the allocation accounting underestimates the final length by a few bytes. The copy proceeds anyway. Those bytes land on adjacent heap chunks.
That is the entire bug in one paragraph. Everything else, including whether it becomes remote code execution or just a worker crash, depends on what is sitting next to the overflowed chunk and how the NGINX slab allocator has been carved up at the time of the request.
Why the rewrite module keeps producing these
The rewrite module has been a recurring source of memory bugs since at least 2013. The reason is structural, not careless coding. NGINX’s rewrite engine is a small bytecode interpreter. Each compiled rewrite directive turns into a sequence of opcodes that push, pop, concatenate, and capture strings on a per-request stack. Length tracking is done by hand at every opcode. There are no length-prefixed strings in the inner loop, no bounds checks at the copy site, and no guard pages between heap chunks. The performance argument for that design is real: NGINX terminates millions of TLS connections per second on commodity hardware partly because it does not pay for safety primitives the rest of the industry takes for granted.
The trade is that any new rewrite opcode, any new variable type, any new capture semantics, has to re-derive the size math correctly. CVE-2026-42945 is what happens when one of those derivations is off by sizeof(uintptr_t) on a specific code path that only triggers when a captured group is reused inside a nested if block. The fuzzers had not hit it because the grammar to reach it is narrow.
What the proof of concept actually does
A working PoC is short. It sends a single HTTP request with a path of roughly 8,100 bytes of A characters, terminated with a marker the rewrite rule expects to capture. The vulnerable config looks like the kind of thing thousands of production sites run: a location ~ ^/(.*)$ block with an if ($arg_x) guard and a rewrite directive that emits $1 into a new URI. The PoC is not exotic. It is curl with a long URL and one query parameter.
What the PoC demonstrates is corruption of the next heap chunk’s size field. On a default build, that chunk usually belongs to the request’s own header pool, so the worker process segfaults on the next allocation and the master restarts it. End of incident, from the operator’s view: a 502 for one client, a line in error.log, no obvious sign of compromise.
The more interesting demonstration, and the one in the public writeup, is what happens when the attacker first sends a few hundred carefully sized requests to shape the heap so that a function pointer inside the SSL session cache ends up adjacent to the overflowed chunk. With the heap groomed, the overflow rewrites the low bytes of that pointer. The next TLS handshake calls into attacker-controlled code. There is no ROP chain in the public PoC. The author stopped at proving control of the instruction pointer, which is the convention for responsible disclosure.
Who is actually exposed
Three groups carry most of the real risk.
First, anyone running NGINX as a reverse proxy in front of an application with user-controllable URL paths. That is most of the public web. The rewrite module is compiled in by default and active in the vast majority of configurations, including the OpenResty and Tengine forks. If your config has any rewrite directive that interpolates a captured group, you are in scope until you patch.
Second, anyone running NGINX as an ingress controller in Kubernetes. The ingress-nginx project ships templated configs that use exactly the pattern the bug needs. A single tenant in a shared cluster can crash the ingress for every other tenant, and on unpatched versions can probably do worse. The blast radius of an ingress compromise in a multi-tenant cluster is the whole cluster.
Third, anyone fronting an LLM inference endpoint with NGINX. This is where the AI safety angle stops being abstract. Most production LLM deployments put NGINX between the public internet and the model server, both for TLS termination and for rate limiting. The model server has read access to its weights, its system prompts, and usually a service account that can reach internal data stores. An attacker who gets code execution in the NGINX worker is one short hop from the inference process. They can read prompts in flight, inject responses, exfiltrate weights if the disk is mounted, or pivot to whatever the inference service can reach.
The AI safety implication people are missing
The usual framing of AI safety incidents is about the model: jailbreaks, prompt injection, training data poisoning. CVE-2026-42945 is a reminder that the model is almost never the soft target. The soft target is the C code sitting in front of it. Every safety guarantee an LLM provider makes, including refusal behaviors, content filters, and rate limits, is enforced at a layer that an attacker with worker-process RCE can bypass entirely. They do not need to jailbreak the model. They can edit the response on the way out.
This matters for the threat model. If you are building a product on top of a hosted LLM and your safety story depends on the provider’s guardrails, you are also depending on the provider’s NGINX patch cadence. That is a dependency most product teams have not written down anywhere. It belongs in the same risk register as the model’s own behavior.
It also matters for self-hosted deployments. The teams running open-weight models inside their own VPCs tend to treat the network edge as solved by virtue of being internal. CVE-2026-42945 is reachable from anywhere that can send an HTTP request to the proxy, which in a typical service mesh is every other pod in the cluster. Internal does not mean trusted, and an LLM endpoint is a high-value target for any attacker who has already established a foothold elsewhere.
What to do this week
Patch to 1.27.5 or 1.26.4, whichever track you are on. The fix is two lines: a corrected size calculation and an added assertion. It is a no-behavior-change patch and there is no excuse to defer it past the next maintenance window.
If you cannot patch immediately, the workaround is to remove rewrite directives that interpolate captured groups, or to cap the matched group length with a more restrictive regex. ^/([^/]{1,256})$ instead of ^/(.*)$ will block the PoC. It will also break any URL longer than 256 characters, so test before deploying.
Check your logs for requests with paths longer than 4KB. The PoC needs roughly 8KB to trigger reliably, but heap grooming attempts will show up as bursts of long-path requests from a single source. Most WAFs already flag this. Most operators ignore the flag because it is usually noise. For the next two weeks it is not noise.
If you run an ingress controller, check what version of NGINX it bundles, not what version is in your distro repos. The ingress-nginx 1.10 series shipped with a vulnerable build for several months. The fix is in 1.10.4 and 1.11.0.
What this tells you about the next one
The rewrite module will produce another heap bug. Probably within eighteen months, based on the historical rate. The structural reasons have not changed: hand-rolled length math, no bounds checks on the hot path, performance as the dominant design constraint. The NGINX team is not going to rewrite it in Rust. The economics do not support it.
The practical response is to stop treating the proxy as infrastructure you can install once and forget. It is application code, with the same patch cadence and the same monitoring requirements as the application behind it. The teams that handle the next one well will be the ones who already know which of their services depend on NGINX, which configs use the rewrite module, and how long it takes them to roll a new build to every edge node. The teams who find out by reading the postmortem will pay for the lesson again.
Keep Reading
nginxNGINX ships emergency patch for HTTP/3 heap overflow
CVE-2026-42945 technical analysis: heap overflow in NGINX HTTP/3 HEADERS frame parsing, worker RCE primitive, telemetry gaps, and patch boundary.
nginxNGINX rewrite module bleeds memory
CVE-2026-42945 places a heap buffer overflow inside NGINX's rewrite module, on the request path. Defect class confirmed. Impact not confirmed.
nginxNginx patched. Assume breach.
NGINX issued the nginx-poolslip patch. Operator analysis of what is confirmed, what is not, and what must change at the proxy boundary.
Stay in the loop
New writing delivered when it's ready. No schedule, no spam.