How to Check and Patch Brotli CVE-2026-111497 (Decoder RCE) in Node.js, Bun, Envoy, Python and Linux

If anything you run decompresses Brotli data it did not create, upgrade it now: Brotli itself to 1.0.10, 1.1.1 or 1.2.1, Node.js to 22.23.4, 24.22.1 or 26.12.1, Bun to 1.4.4, and Envoy to 1.40.0 or the fixed patch release for your line. CVE-2026-111497 is an out-of-bounds write in the Brotli decoder (c/dec/decode.c). The CVE record, published by Google on October 22, 2026, says a “remote unauthenticated attacker” can use “a crafted Brotli-compressed stream” to corrupt decoder memory, leak memory contents, crash the process “or potentially execute arbitrary code.” It is rated CVSS 4.0 9.2 (Critical). The bug was reported by OpenAI Codex Security researchers Khai Tran and Sylvie Mayer, and OpenAI announced the finding on October 24 (Beijing time) as part of its red-teaming work. Brotli is embedded almost everywhere HTTP compression happens, so the hard part is not the upgrade. It is finding every copy.

This guide walks through that in order: what is affected, how to check each runtime, one important gotcha with version strings, how to patch, and what to do if you can’t patch today. Every version number below comes from the CVE-2026-111497 record, the Brotli releases, the Node.js October 2026 security release, the Bun v1.4.4 release notes, Envoy’s GHSA-3wvj-j6qm-62mr advisory, the Debian security tracker and OSV. We did not build or run any exploit.

What the bug is, in one minute

Brotli is Google’s compression format, best known as the br value of the HTTP Content-Encoding header. Browsers, CDNs, proxies, language runtimes and package managers all ship a decoder for it.

The Node.js advisory gives the clearest description of the root cause: “An invalid block switch was reported as a temporary need for more input instead of a permanent format error, so the streaming decoder kept appending input bytes to an eight-byte internal buffer.” In other words, a malformed stream that should have been rejected immediately instead kept the decoder asking for more bytes, and those bytes were written past the end of a tiny buffer. The CVE record classifies this as CWE-787 (out-of-bounds write) together with CWE-252 (unchecked return value).

The upstream fix is a single commit titled “Detect and report invalid stream earlier,” shipped on October 21, 2026 in three maintenance releases, one for each supported line:

Brotli lineAffectedFixed
1.0.x1.0.3 to 1.0.91.0.10
1.1.x1.1.01.1.1
1.2.x1.2.01.2.1

Two details from the CVSS vector matter for prioritising. The attack vector is network, with no privileges and no user interaction needed. But “attack requirements” is set to present: the attacker has to get crafted Brotli data into a decoder you run. That happens in two common ways:

  1. Servers that accept compressed request bodies. If your API, proxy or upload handler decodes Content-Encoding: br on incoming requests, any client can send the payload.
  2. Clients that accept compressed responses. If your code fetches URLs and lets the HTTP client decode br automatically, the server on the other end (or anyone who can tamper with that response) can send the payload. This is the scenario that makes the bug relevant to crawlers, scrapers, webhook consumers, RAG ingestion jobs and AI agents that browse the web.

Only decompression is affected. Code that only compresses with Brotli is not in the scope of this CVE.

Step 1: Inventory every place Brotli is decoded

Before upgrading anything, list where a Brotli decoder lives on each host or image. In practice there are four buckets:

  • The system library (libbrotli1 on Debian and Ubuntu, brotli on Alpine), used by curl, nginx and Apache Brotli modules, and by any distro-packaged runtime that links it dynamically.
  • A copy bundled inside a runtime, which the system library update does not fix. Official Node.js binaries, Bun and Envoy all carry their own Brotli.
  • Language bindings that compile their own copy, such as the Brotli and brotlicffi Python packages.
  • Container images, which freeze all of the above at build time.

On a Debian or Ubuntu host, start with the package and the shared libraries that depend on it:

# Installed Brotli package version
dpkg -l | grep -i brotli

# Which running processes have the system decoder mapped (needs root to see other users' processes)
sudo grep -l libbrotlidec /proc/*/maps 2>/dev/null | cut -d/ -f3 | xargs -r ps -o pid,cmd -p

On Alpine:

apk info -v | grep -i brotli

For curl specifically, curl -V prints the decoder it was built against on the first line, for example brotli/1.1.0, and ldd $(which curl) shows whether it loads libbrotlidec.so.1 from the system. If it does, updating the system package fixes curl.

Step 2: Check Node.js (and don’t trust process.versions.brotli)

The Node.js project shipped fixes on October 21, 2026 in v22.23.4, v24.22.1 and v26.12.1, and lists all three active lines (22.x, 24.x and 26.x) as affected. End-of-life lines are not getting a fix; the advisory notes that “End-of-Life versions are always affected when a security release occurs.”

Check the version that actually runs in production, not just the one on your laptop:

node -v

You are fixed if the output is at least v22.23.4, v24.22.1 or v26.12.1 on your line.

The gotcha: Node exposes the bundled Brotli version as process.versions.brotli, and it is tempting to check that instead. Don’t. We downloaded the official patched node-v22.23.4-linux-x64 build and ran:

node -p 'process.versions.brotli + " " + process.version'
# 1.1.0 v22.23.4

The patched release still reports Brotli 1.1.0, the same string as the vulnerable v22.23.3. The fix was applied to Node’s bundled copy without changing the version string, so a scanner or script that flags “brotli < 1.1.1” will report patched Node 22 hosts as vulnerable, and a script that trusts the string cannot tell the two apart. Use the Node.js version as your source of truth.

In the Node advisory’s words, an application is exposed if an attacker “can supply Brotli data that an application decompresses with node:zlib.” Search your code and dependencies for the Brotli decompression APIs to understand where that happens:

grep -rnE "brotliDecompress|createBrotliDecompress|BrotliDecompress" --include=*.{js,mjs,cjs,ts} . | grep -v node_modules/.cache

Remember that HTTP client and server libraries can call these for you when they handle Content-Encoding: br, so an empty grep of your own code is not proof that you are safe. Upgrade regardless.

Distro-packaged Node is different

If you installed Node from Debian’s own repositories rather than from nodejs.org or NodeSource, Debian’s tracker notes that “nodejs uses system provided brotli library” and marks the nodejs package itself as unimportant for this CVE. For those hosts the fix is the system libbrotli1 update in Step 4, followed by a restart of every Node process.

Step 3: Check Bun

Bun ships its own Brotli. The Bun v1.4.4 release, published on October 22, 2026, includes security fixes whose list of affected areas explicitly names Brotli (alongside TLS, HTTP/1.1, HTTP/2, HTTP/3, WebSocket, fetch and others). Bun does not expose a process.versions.brotli value, so the Bun version is the only check:

bun --version

Anything below 1.4.4 should be upgraded:

bun upgrade

If you pin Bun in CI (for example with oven-sh/setup-bun and a bun-version input) or in a Dockerfile base image like oven/bun:1.4.3, bump the pin as well. bun upgrade only updates the copy on the machine where you run it.

Step 4: Patch the system library (Debian, Ubuntu, Alpine)

As of October 24, 2026, the distro status looks like this:

DistroReleaseFixed packageStatus
Debian 12 bookwormsecurity1.0.9-2+deb12u1fixed (DLA-4855-1)
Debian 13 trixiesecurity1.1.0-2+deb13u1fixed (DSA-6582-1)
Debian forky / sid1.2.0-4still vulnerable
Ubuntu (all listed releases)“Needs evaluation” on the Ubuntu CVE page
Alpinev3.21 and newer branchese.g. 1.1.1-r0 on v3.21fixed per OSV

On Debian:

sudo apt update
sudo apt install --only-upgrade libbrotli1
dpkg -l libbrotli1   # expect 1.0.9-2+deb12u1 (bookworm) or 1.1.0-2+deb13u1 (trixie) or later

On Alpine:

apk update && apk upgrade
apk info -v | grep -i brotli   # confirm the fixed package version for your branch

Ubuntu had not published fixed packages when we checked. Watch the Ubuntu CVE page and run sudo apt update && sudo apt upgrade as soon as the status changes.

Restart what uses it. A shared-library update does nothing for processes that already have the old library mapped in memory. After upgrading, rerun the /proc/*/maps check from Step 1, or use needrestart if you have it installed, and restart nginx, Apache, Node and anything else that still holds the old file.

Second version-string gotcha: Debian fixed bookworm and trixie by backporting the patch into the existing 1.0.9 and 1.1.0 packages. Tools that print the library’s own version, such as curl -V, will typically keep showing brotli/1.1.0 after the update. Trust the package version (+deb13u1), not the upstream version string.

Step 5: Check Envoy and other proxies

Envoy’s advisory, rated critical, says the Brotli decompressor bug is “addressed in Envoy v1.40.0, v1.39.3, v1.38.6, v1.37.8 and v1.36.12,” and scopes the impact to “Envoy deployments that have Brotli decompressor configured.” In October 2026 Envoy also published newer patch releases on each line (v1.40.1, v1.39.5, v1.38.8 and v1.37.10), so the simplest instruction is to move to the latest patch release of your line.

Check your version and whether the filter is in use:

envoy --version

# Look for the Brotli decompressor extension in your bootstrap or xDS dumps
grep -rn "compression.brotli.decompressor" /etc/envoy/

If you run Envoy under Istio, Contour, Emissary or another control plane, the Envoy binary comes with the control-plane release, so check that project’s release notes for the bundled Envoy version rather than upgrading Envoy directly.

For nginx and Apache, the Brotli modules (ngx_brotli, mod_brotli) normally link the system library, so Step 4 plus a restart covers them. Most deployments of these modules only compress responses, which is outside the scope of this bug, but patch anyway: the decoder lives in the same library package.

Step 6: Check Python and other language bindings

OSV lists two Python advisories that map to this CVE:

PackageFixed inAdvisory
Brotli (Google’s official bindings)1.2.1PYSEC-2026-4322
brotlicffi1.2.1.0PYSEC-2026-4323

Both were published to PyPI on October 22, 2026. Check and upgrade:

pip show Brotli brotlicffi 2>/dev/null | grep -E "^(Name|Version)"
pip install --upgrade "Brotli>=1.2.1" "brotlicffi>=1.2.1.0"

Then pin the minimum version in requirements.txt, pyproject.toml or your lock file so a fresh install can’t pull an old wheel back in.

This matters more in Python than it might look. urllib3, the library under requests, lists br among its default CONTENT_DECODERS and has a BrotliDecoder class, so when one of these packages is installed, ordinary requests.get() calls can transparently decode Brotli responses from whatever server they talk to. A scraper or ingestion worker that fetches arbitrary URLs is exactly the “client accepting compressed responses” case from the start of this guide.

For other ecosystems, the CVE record lists only Google’s C library (github.com/google/brotli) as affected. Pure-language reimplementations, such as the Rust and Go ports, are separate codebases that this CVE does not cover. Check your own dependency scanner (npm audit, pip-audit, osv-scanner, Dependabot) and the project’s advisories rather than assuming either way.

Step 7: Rebuild container images

Containers are where this bug will linger longest, because every image froze its own Brotli, Node or Bun at build time. For each service image:

docker run --rm --entrypoint sh your-image:tag -c 'node -v 2>/dev/null; bun --version 2>/dev/null; (dpkg -l libbrotli1 || apk info -v | grep -i brotli) 2>/dev/null'

Then rebuild with --pull so the base image is refreshed, bump any pinned node:, oven/bun: or envoyproxy/envoy: tags to the fixed versions, and redeploy. If you run an image scanner such as Trivy, Grype or Docker Scout, rescan after the rebuild. For Node images, expect the scanner to rely on the Node version rather than on process.versions.brotli, for the reason explained in Step 2.

If you can’t patch today

These are stopgaps that reduce exposure while you schedule the real fix. None of them replaces the upgrade.

  • Stop decoding Brotli you didn’t produce. On servers, reject requests with Content-Encoding: br at the edge (a WAF rule, a proxy route match or a middleware check) unless a client genuinely needs to upload Brotli bodies.
  • Turn off br in outbound clients. For crawlers and agents that fetch untrusted URLs, send Accept-Encoding: gzip, deflate explicitly so well-behaved servers don’t reply with Brotli. A hostile server can ignore the header, so this only narrows the window.
  • Remove the Envoy Brotli decompressor filter from listeners until the proxy is upgraded, if your traffic allows it.
  • Isolate fetch workers. If you run agents or ingestion jobs that download content from the open web, keep them in a sandbox with no access to credentials or internal networks. Our guide to sandboxing AI agents with NVIDIA OpenShell covers one way to do that.

Verification checklist

Before closing the ticket, confirm each item:

  • node -v is at least v22.23.4, v24.22.1 or v26.12.1 everywhere Node runs, including CI runners and container images.
  • bun --version is 1.4.4 or later everywhere Bun runs.
  • libbrotli1 (Debian) or the Alpine Brotli packages are at the fixed package version, and no running process still maps the old library.
  • Envoy is on v1.40.0 or later, or on the fixed patch release of your line, or the Brotli decompressor is not configured.
  • Python environments have Brotli>=1.2.1 and brotlicffi>=1.2.1.0, with the minimums pinned.
  • Container images have been rebuilt with --pull and redeployed, not just patched on the host.

FAQ

Is this being exploited in the wild? None of the sources we used (the CVE record, the Node.js, Bun and Envoy advisories, and the Debian tracker) reports exploitation in the wild as of October 24, 2026. That can change quickly once a bug of this kind is public, so treat it as urgent.

Does compressing with Brotli make me vulnerable? Not according to the CVE description, which places the bug in the decoder. You still need the patched library because the encoder and decoder ship in the same packages.

My scanner says Node 22.23.4 is vulnerable because it bundles Brotli 1.1.0. Is it wrong? Most likely, yes. As shown in Step 2, the patched official v22.23.4 build still reports process.versions.brotli as 1.1.0. Node’s advisory lists v22.23.4 as the fixed release for the 22.x line.

Browsers ship Brotli too. Do I need to do anything? Browsers use their own builds of the decoder and update through their normal release channels. Keep them updated as usual. The sources above do not list specific browser versions, so we don’t either.

Who found it, and how? The CVE record and the Node.js advisory credit Khai Tran and Sylvie Mayer of OpenAI Codex Security, and Envoy’s advisory credits OpenAI Security Research. If you want to run the same kind of AI-assisted vulnerability scanning on your own code, see our Codex Security CLI guide. For another critical bug from the same week with a similar response playbook, see how to check and patch GitLab CVE-2026-110264. More security guides are on the 7minai homepage.

Sources