Skip to main content
SecurityJuly 15, 202610 min read

nginx Patches Three CVEs, One a 9.2 Critical Bug That Sat Hidden in the Code Since 2011

nginx patched three CVEs on July 15, 2026: a 9.2-rated critical heap buffer overflow in map regex matching (CVE-2026-42533) present since 2011, an uninitialized-memory bug that unnamed regex captures trigger through either the slice directive or ordinary background cache updates (CVE-2026-60005), and a use-after-free in the SSI filter (CVE-2026-56434) present since 2009. Fixed in 1.30.4 stable and 1.31.3 mainline. With the config patterns to audit for, five read-only audit commands, and the detail most coverage gets wrong about the second bug.

Three Bugs, One Release, and Fifteen Years of Quiet Exposure

nginx shipped a security release on July 15, 2026 that patches three separate vulnerabilities at once, and the timeline behind them is the part that should worry you more than the patch notes do. The worst of the three, a heap buffer overflow rated 9.2 CRITICAL, has been sitting in the map directive's regex handling since nginx 0.9.6, released back in March 2011. Another, a use-after-free in the SSI filter, is older still, present since version 0.8.11 in August 2009, almost seventeen years before anyone found it.

The scale is what makes this worth an hour of your week. According to W3Techs, nginx runs 31.5 percent of every website whose web server is known. A bug that has been in the map directive since 2011 has therefore been shipping inside roughly a third of the web for fifteen years. The fixes landed in nginx 1.30.4 on the stable branch and 1.31.3 on mainline, both dated July 15, 2026. If you have not upgraded past those versions, all three bugs are live in your worker processes right now.

The Three at a Glance

CVEWhat it isCVSS 3.1CVSS 4.0Present sinceIn a default build?
CVE-2026-42533Heap buffer overflow in map with regex8.1 HIGH9.2 CRITICAL0.9.6 (Mar 2011)Yes
CVE-2026-60005Uninitialized memory access, unnamed captures8.2 HIGH8.8 HIGH1.15.8 (Dec 2018)Partly, see below
CVE-2026-56434Use-after-free in the SSI filter6.5 MEDIUM8.3 HIGH0.8.11 (Aug 2009)Module yes, SSI must be on

Two things in that table are worth pausing on. First, the CVSS 4.0 column is consistently harsher than 3.1, and for CVE-2026-42533 it crosses into CRITICAL. Second, some coverage has been repeating the "Medium" label that nginx's own advisory page attaches to CVE-2026-60005. NVD scores it 8.2 and 8.8, both HIGH. When a vendor label and NVD disagree this widely, patch to the higher number.

How Long Each Bug Sat There

2009  •──────────────────────────────────────────────────┐  CVE-2026-56434  (SSI)
      0.8.11                                             │  ~16 years, 11 months
                                                         │
2011  ──────•────────────────────────────────────────────┤  CVE-2026-42533  (map regex)
            0.9.6                                        │  ~15 years, 4 months
                                                         │
2018  ─────────────────────────────•─────────────────────┤  CVE-2026-60005  (captures)
                                   1.15.8                │  ~7 years, 7 months
                                                         │
2026  ───────────────────────────────────────────────────•  all three patched
                                          1.30.4 / 1.31.3   15 Jul 2026

What the Changelog Actually Says

Secondary coverage of these three has been sloppy, so here is nginx's own changelog wording, which is the authoritative description and more precise than most of what has been written about it.

On CVE-2026-42533:

"heap buffer overflow might occur in a worker process when using the map directive with regex matching if the map variable was included in a string expression after a capture affected by this map; a similar issue might happen when using a non-cacheable variable in a string expression"

Note the second half of that sentence. There are two trigger paths, not one, and the second involves non-cacheable variables with no map in sight. Credit for the find goes to Mufeed VH of Winfunc Research and to Maxim Dounin.

On CVE-2026-60005:

"uninitialized memory access might occur when using unnamed regex captures with the "slice" directive or background cache update, which could result in worker process memory disclosure or worker process termination"

This is the one most write-ups get wrong, including our own first cut at this story. The bug is not really "a slice module bug". The trigger is unnamed regex captures, and the slice directive is only one of two paths to it. The other is background cache update, which is the ordinary proxy_cache_background_update directive, present in a stock build with no special compile flag. If you concluded you were safe because you did not build with --with-http_slice_module, check again for background cache updates.

On CVE-2026-56434:

"use-after-free might occur when processing a specially crafted proxied backend response with the ngx_http_ssi_filter_module"

The important phrase is "proxied backend response". The malicious input arrives from the upstream you are proxying to, which is why NVD's vector requires a man-in-the-middle position or a compromised backend rather than a plain anonymous request. Credit to P4P3R-HAK.

The Pattern to Look For in Your Config

For CVE-2026-42533, the shape described in the advisory is a regex map whose capture variable is referenced in a string expression before the map's own output variable. Something structurally like this:

map $uri $backend_pool {
    ~^/(?<app>[a-z]+)/   "pool_$app";
    default              "pool_default";
}

server {
    location / {
        # $app is a capture affected by the map above.
        # The map variable $backend_pool then appears in a string
        # expression after that capture. This is the shape the
        # advisory describes.
        proxy_set_header X-App  $app;
        proxy_set_header X-Pool "$app-$backend_pool";
        proxy_pass http://$backend_pool;
    }
}

Treat that as the pattern to audit for, not as a proof of concept. Regex maps are an unremarkable, everyday nginx pattern used for routing, header rewriting, feature flags, and A/B splits, which is exactly why this bug has such a wide blast radius. There is no build flag protecting you from it.

For CVE-2026-60005, the distinction is named versus unnamed captures, and F5's own recommended mitigation is to switch to named ones:

# Unnamed captures ($1, $2) with slice or background cache update:
# this is the combination CVE-2026-60005 needs.
location ~ ^/files/(.+)/(.+)$ {
    slice 1m;
    proxy_cache_background_update on;
    proxy_pass http://backend/$1/$2;
}

# Named captures: F5's recommended mitigation if you cannot
# patch immediately.
location ~ ^/files/(?<dir>.+)/(?<file>.+)$ {
    slice 1m;
    proxy_cache_background_update on;
    proxy_pass http://backend/$dir/$file;
}

Named captures are a mitigation, not a fix. Patch anyway.

Audit Your Fleet in Five Commands

Every one of these is read-only and safe to run on production.

# 1. What version is actually running? (Not what the package manager thinks.)
nginx -v

# 2. Was the slice module compiled in?
nginx -V 2>&1 | tr ' ' '\n' | grep -- '--with-http_slice_module' \
  && echo "slice module PRESENT" || echo "slice module absent"

# 3. Regex maps: the widest exposure, CVE-2026-42533.
nginx -T 2>/dev/null | grep -nE '^\s*map\s+.*\s+\$' -A5 | grep -nE '~|\$'

# 4. The background-cache-update path to CVE-2026-60005,
#    which needs no build flag at all.
nginx -T 2>/dev/null | grep -nE 'proxy_cache_background_update\s+on'

# 5. Is SSI actually switched on anywhere? (CVE-2026-56434)
nginx -T 2>/dev/null | grep -nE '^\s*ssi\s+on'

nginx -T is the important one. It dumps the full effective configuration with every include resolved, which is where the map buried in a vendor snippet three includes deep finally shows itself. Grepping nginx.conf alone will miss it.

Across a fleet, the same audit in one pass:

# Adjust the host list to taste. Read-only, no changes made.
for host in $(cat hosts.txt); do
  echo "=== $host ==="
  ssh "$host" '
    nginx -v 2>&1
    nginx -V 2>&1 | tr " " "\n" | grep -c -- "--with-http_slice_module" \
      | sed "s/^/slice_module_flag: /"
    nginx -T 2>/dev/null | grep -cE "proxy_cache_background_update\s+on" \
      | sed "s/^/background_cache_update: /"
    nginx -T 2>/dev/null | grep -cE "^\s*ssi\s+on" \
      | sed "s/^/ssi_on: /"
  '
done

What the Version Numbers Mean

nginx runs two branches and the naming trips people up, so to be explicit:

BranchVulnerablePatchedWho runs it
stable0.9.6 through 1.30.31.30.4Most distribution packages, production installs
mainline1.31.2 and earlier1.31.3Newer feature adopters, some containers

If your distribution ships an older nginx with backported patches, the version string will not tell you the whole story. Check your vendor's security tracker for these three CVE IDs rather than comparing version numbers to the upstream table.

The One That Matters Most

CVE-2026-42533 is the bug to lose sleep over, and not only because of the score. It sits in code that has processed every regex-based map directive written in the last decade and a half. The failure mode is a heap overflow in the worker process, and the advisory states plainly that this can lead to denial-of-service or, when address space layout randomization is disabled, code execution.

That ASLR qualifier is doing a lot of work in how this bug reads, and it is worth being precise rather than either panicking over it or waving it away. ASLR ships on by default across essentially every current Linux distribution. But ASLR is a mitigation, not a lock, and bypasses are a well established category of attack technique, not a theoretical curiosity. Some containerized environments and some hardened or embedded builds run with ASLR weakened or disabled for reasons that have nothing to do with this bug, and those are exactly the environments where the code-execution path stops being hypothetical. Treat the CRITICAL score as the operative number, and treat ASLR as a second layer that may already be thinner than you assume, not as a reason to move slower.

Who Is Actually Exposed

Ranked by how likely this is to be you:

  • Highest: anyone running a regex map. CVE-2026-42533 needs no special module and no unusual build. Regex maps are everywhere. If command 3 above returns anything, you are in this group.
  • High and widely underestimated: anyone using background cache updates. The proxy_cache_background_update on directive plus unnamed regex captures reaches CVE-2026-60005 with a stock build. This is the path most coverage skips.
  • Real but build-dependent: slice module users. Only if --with-http_slice_module was compiled in, which stock builds usually skip but plenty of custom builds and some distribution packages include.
  • Narrow: SSI with a hostile upstream. CVE-2026-56434 needs ssi on and a crafted response from the backend you proxy to, which means a compromised upstream or a man-in-the-middle position. Real, old, worth patching, not an emergency on its own.

What to Do Now

Upgrade to nginx 1.30.4 on stable or 1.31.3 on mainline. There is no configuration workaround for CVE-2026-42533 short of removing regex maps entirely, so patching is the only real fix. Sequence it like this:

  1. Run the five audit commands across the fleet and sort hosts into exposed and not. The regex-map check decides most of it.
  2. Patch the regex-map hosts first. That is the CRITICAL one and the one with no escape hatch.
  3. Switch unnamed captures to named ones on any host using slice or background cache update, if you cannot patch it in the same window. Mitigation, not cure.
  4. Rebuild container images that bundle nginx and redeploy them. A host package update does nothing for nginx running inside a container built from an older base layer.
  5. Restart the workers. nginx -s reload picks up config, but a binary upgrade needs the master process restarted or the binary hot-swapped. A patched package with an unrestarted process is still the vulnerable code in memory.
  6. Verify with nginx -v on every host after the roll, not just the ones you remember touching.

Fifteen years is a long time for a critical bug to sit unnoticed in software running a third of the web. That is not a reason to panic about nginx as a project, researchers and maintainers found and fixed this exactly the way the process is meant to work, but it is a reason to run the upgrade this week rather than filing it under someday. The regex-map check takes about thirty seconds per host and tells you whether this is urgent for you specifically.

If you want a fast audit of which hosts run vulnerable configurations, which builds have the slice module compiled in, and how to sequence the upgrade across a fleet without downtime, that is exactly what our security and compliance and server management work covers. For another case of a critical bug hiding in plain sight for over a decade, see our note on the Januscape KVM escape.

Sources

Talk to the engineer who will own your stack.

No account managers, no offshore handoff. Senior DevOps, direct. Tell us what you are dealing with and you get a straight answer.

Related News

Security

The New cPanel Critical Bug Needs a Valid Login and Still Outscores April's Unauthenticated Root Flaw

CVE-2026-58048, published July 31, 2026, is a 9.4 critical privilege escalation in cPanel and WHM: renaming a database fails to preserve SQL mode, so a customer's SQL executes in root context. It requires a valid cPanel account and the MySQL feature, which sounds reassuring until you compare the scores. April's unauthenticated authentication bypass rated 9.3. This one needs a login and rates 9.4, and the entire difference lives in the CVSS 4.0 subsequent-system metrics: the CNA scored this as breaking out of the account and taking the host with it. On a shared server that means any tenant, including one who paid for a month. Covers the exact first-fixed builds per release tier, the quieter companion CVE, and why automatic updates are the answer to a different question.

Security

The wp2shell WordPress RCE Is Real, but Three Conditions Decide Whether Your Site Is Actually Exposed

wp2shell (CVE-2026-63030) chains a REST API batch route confusion with the author__not_in SQL injection (CVE-2026-60137) into a pre-auth RCE on WordPress core, fixed July 17 in 6.9.5, 7.0.2 and 6.8.6. The headline is true: an anonymous request can run code on a default install. But three conditions decide real exposure, the version, whether a persistent object cache is in use, and whether auto-updates already patched you. Here is what NVD and WordPress actually say, the CVSS scores that disagree, and a two-minute check for your own sites.

Security

A 16-Year-Old KVM Bug Called Januscape Lets a Guest VM Break Out to the Host on Intel and AMD

Januscape (CVE-2026-53359) is a 16-year-old use-after-free in the Linux KVM shadow MMU on both Intel and AMD, rated a guest-to-host escape by Canonical. The public proof of concept crashes the host from inside a guest, while full host takeover is claimed but not published. Upstream fixed it on July 4, but distro kernels are still pending. Here is who is exposed, the nested-virtualization mitigation, and what to do now.