CVE-2026-111497 is an out-of-bounds write in Google's Brotli decoder. OpenAI disclosed it on October 24, 2026 after a red-teaming exercise, and said an unpatched server that accepts compressed input "could be taken over by a malicious client," while an unpatched client such as curl --compressed "could be taken over by a malicious server." The CVE record gives CVSS 4.0 a score of 9.2. Node.js rates it High.
We already covered the Node.js side and listed the entry in the CVE database. This post covers what changed since: the same decoder lives in many other runtimes, and the fix has to travel through each of them. For a plain-English version, read the explainx.ai guide.
Quick reference
| Item | Detail |
|---|---|
| CVE | CVE-2026-111497 |
| Weakness | CWE-787 out-of-bounds write; CWE-252 unchecked return value |
| Affected Brotli | 1.0.3 to 1.0.9, 1.1.0, 1.2.0 |
| Fixed Brotli | 1.0.10, 1.1.1, 1.2.1 |
| Upstream fix commit | February 27, 2026, no release at the time |
| Score | CVSS 4.0: 9.2 (CVE record); Node.js severity: High |
| In CISA KEV | No, as of October 23, 2026 |
| Exploitation in the wild | None reported as of October 23 |
| Public proof of concept | Yes; crash on several Node.js builds, code execution shown on Node.js 24.22.0 arm64 |
How the bug works
The Node.js advisory describes the root cause as an invalid block switch reported as a temporary need for more input rather than a permanent format error. The streaming decoder kept consuming input into an internal buffer of only eight bytes. Cycode describes the trigger as a stream that declares a single block type and then switches blocks; the decoder did not reject it and continued in an invalid state until it wrote past a buffer.
The upstream fix makes the decoder stop and return an error at the first sign of a bad stream. Node.js exposes the new error as BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH. Seeing that code in logs after an upgrade means the fixed decoder rejected a malformed stream.
Because the decoder is C code, a successful write corrupts memory in the host process. Outcomes range from a crash, to disclosure of process memory, to code execution with the privileges and environment of that process.
Fixed releases by ecosystem
| Ecosystem | Fixed in | Notes |
|---|---|---|
| Node.js | 22.23.4, 24.22.1, 26.12.1 | 20.x, 25.x and older get no fix |
| Bun | 1.4.4 (released October 22) | Advisory GHSA-663w-cv8g-jj2p; rebuild bun build --compile binaries |
Python Brotli | 1.2.1 | GHSA-9v8h-qqgm-4m35, rated critical |
Python brotlicffi | 1.2.1.0 | |
| Envoy | 1.40.0, 1.39.3, 1.38.6, 1.37.8 | 1.36.12 has the fix but 1.36 is unsupported |
| Istio | 1.29.9, 1.30.6, 1.31.2 | 1.29 is end of life |
| libbrotli | 1.0.10, 1.1.1, 1.2.1 | Distributions may backport |
| curl / libcurl | Depends on the Brotli it loads | Use 1.2.1 or a vendor-patched package |
Debian brotli | bookworm 1.0.9-2+deb12u1 | trixie 1.1.0-2 and unstable 1.2.0-4 listed as vulnerable when Brandefense checked |
We did not verify fixed versions for Chromium, Go modules, Rust crates or Java libraries, and the sources we read do not cover them. Do not assume they are safe or unsafe; check the dependency tree.
How each runtime reaches the decoder
Node.js
Node.js bundles Brotli under deps/brotli and exposes it through node:zlib. Cycode and Semgrep list these routes: Express 5 with body-parser 2.x when inflation is on, the Koa body parsers, @fastify/compress with request decompression, direct zlib.createBrotliDecompress() calls, and fetch() reading attacker-influenced responses. Express 4 and body-parser 1.x do not decode Brotli request bodies.
Python
The risk is easy to miss because your code need not import Brotli. urllib3 (and so requests), httpx with the brotli extra, aiohttp and Scrapy load the package automatically when it is installed and accept br responses. A malicious server can then answer your request with a crafted stream. Aikido notes that the OSM researchers did not pursue memory corruption or code execution in the Python extension, so impact there may be limited to a crash, but treat it as in scope.
Native code, proxies and curl
Any C or C++ program that links libbrotlidec is in scope, including curl builds with Brotli support. Envoy and Istio bundle it for their compression filters. Aikido says Apache's standard mod_brotli does not decode Brotli and Nginx does not decode it by default, so those are mainly out of scope unless you added a decoding module.
Detect exposure
Start with an inventory, then narrow to paths that touch untrusted data.
# runtimes
node -v
bun --version
docker run --rm <your-image> node -v
# python, in every venv and image
pip show Brotli brotlicffi
pipdeptree -r -p Brotli
grep -i brotli poetry.lock uv.lock requirements*.txt
# native
curl -V | grep -i brotli
ldconfig -p | grep -i brotli
Then search code for decode paths:
grep -rnE "express\.json|bodyParser|createBrotliDecompress|brotliDecompress|@fastify/compress" src/
Two caveats from the sources. First, a moving tag such as node:24 gives no verdict; check the version inside the running container. Second, scanners lag: Aikido reports pip-audit, Dependabot and Safety did not flag the Python versions as of October 23, so a clean scan is not proof.
Runtime signs of attempts include segmentation faults or aborts inside zlib or Brotli frames right after a compressed request or response, repeated worker crashes on one endpoint, or a process that suddenly spawns shells or opens unexpected outbound connections.
Fix and interim mitigation
- Upgrade the runtime or package from the table above.
- Restart every process and rebuild images with
docker build --pull; a running process keeps the old native code. - Rebuild standalone binaries (
bun build --compile, Node.js single executables), since they carry their own copy. - Move off end-of-life Node.js lines.
If you cannot patch yet, reduce what reaches the decoder, knowing this is partial:
- Reject
Content-Encoding: brat the proxy or load balancer, matching case-insensitively and inside lists such asgzip, br. Brandefense labels this its own suggestion, not vendor advice. - In Express,
express.json({ inflate: false })disables body decompression, which also rejects gzip bodies. Test clients first. - Stop advertising
brinAccept-Encodingfrom clients that fetch untrusted URLs.
Neither step guards every client path, and Node.js lists no workaround. Treat them as a bridge to the upgrade.
Why agents and MCP servers deserve a second look
A fetch or browse tool reads responses from servers it does not choose. An attacker does not need to reach your network: a poisoned page or prompt injection that points an agent at an attacker URL is enough to put a crafted br response in front of the client. The explainx.ai coverage of AI-era attack timelines applies here too: exploit code appears quickly once a patch is public.
For agent hosts, the checklist is short: patch the runtimes behind MCP servers and agent CLIs, run them as unprivileged users, keep long-lived cloud and model keys out of their environment, and watch what a tool launches. Beam records the shell commands and network tools coding agents run, which helps spot a process doing something it never did before.
What we could not confirm
- Attacks in the wild: none reported as of October 23.
- Large package counts circulating on social media: no published list found in the sources we read.
- Reliable code execution: public proofs of concept differ. One crashes several Node.js builds without claiming code execution, one claims local code execution under specific conditions, and Aikido reports execution on Node.js 24.22.0 arm64 that did not work on every attempt.
Related reading
- Node.js October 2026 security release: MCP servers and agent tools
- PHP2Shell and AI agents: why the attack window collapsed
- PHP2Shell patch guide for Ubuntu, Debian, RHEL and Docker
- CVE-2026-111497 database entry
- Brotli bug explained for builders on explainx.ai
Primary sources: Patch the Planet: Brotli · Node.js October 2026 security releases · Cycode · Aikido · Brandefense · Qualys
Versions and exploitation status are accurate as of October 24, 2026 and may change as vendors publish advisories.
