Brotli decoder flaw lets a malicious server take over Node.js and Python apps

24.10.2026 4 min 17

A bug in Google's Brotli decoder lets a crafted stream of compressed data write past the end of a buffer in memory. Tracked as CVE-2026-111497 and rated 9.2 out of 10 in GitHub's advisory, it affects Brotli versions 1.0.3 through 1.2.0. Brotli is the compression format behind much of today's web traffic, so the flaw reaches far beyond one library: Node.js, Bun, Envoy, Istio and the Python packages that requests and aiohttp use on their own all bundle or load the vulnerable code. Fixes shipped on 21 to 23 October.

What goes wrong

A Brotli stream is split into blocks, and the decoder switches between block types as it reads them. According to the Node.js advisory, an invalid block switch was treated as a temporary need for more input rather than as a format error. The decoder then kept appending attacker bytes to an eight-byte internal buffer and wrote past its end. Depending on what gets overwritten, the result is a crash, a leak of process memory or remote code execution.

The flaw was reported to Node.js by Khai Tran and Sylvie Mayer of OpenAI Codex Security. Google released fixed Brotli versions 1.0.10, 1.1.1 and 1.2.1, and Node.js shipped 22.23.4, 24.22.1 and 26.12.1 on 21 October. Node.js 20 and other end-of-life lines get no fix.

The attack works both ways

The decoder runs wherever compressed data arrives, so either side of a connection can be the target. A malicious server can attack a client: Node's built-in fetch() decodes Brotli responses automatically, and so do Python's requests, urllib3 and aiohttp whenever a Brotli package is installed. An app does not need to import the package for this to happen. Webhooks, link previews, crawlers and "import from URL" features all fetch content from servers that someone else controls.

In the other direction, a client can attack a server that decompresses request bodies. Express 5.0.0 to 5.3.0 and body-parser 2.0.0 to 2.3.0 inflate Brotli bodies in their raw() and json() parsers. Imperva's Red Team ran attacker-supplied code on the official Node.js 24.22.0 image through both paths: a fetched response and an Express request body. It took several attempts, and Imperva has not released the exploit.

How far it reaches

The bug is in Google's reference C decoder, and many projects ship a private copy of it. A tracker of affected software at broccoli2shell.com lists fixes for Bun 1.4.4, Envoy, Istio, Chromium, Firefox, ngx_brotli and the Python packages Brotli 1.2.1 and brotlicffi 1.2.1.0. As of 24 October it still listed unpatched copies in the .NET runtime, the PHP and Ruby brotli extensions, DuckDB, ClickHouse, Apache Arrow, the JPEG XL library, 7-Zip forks and MuPDF.

Linux distributions patch the shared libbrotli library separately. Debian, for example, fixed it in security updates for bookworm and trixie. A public proof of concept appeared on GitHub on 22 October, though it reportedly reaches code execution only on a deliberately weakened build. No attacks in the wild had been reported by then.

What to check

  • Browsers: Chrome, Edge and Firefox decode Brotli on almost every page. Install the latest update and restart the browser.
  • Node.js and Bun: run node --version. Anything below 22.23.4, 24.22.1 or 26.12.1, or on an end-of-life line such as 20, needs an upgrade. Bun needs 1.4.4 or later.
  • Python: run pip show Brotli brotlicffi. If either is older than 1.2.1, upgrade it, or uninstall it so that requests falls back to gzip.
  • Servers: apply the distribution's libbrotli update, then restart every service that loads it. A running process keeps the old decoder in memory until it restarts.

That last point is easy to miss. On a server, the package manager can install the fix overnight while PHP, Python or other long-running workers keep using the vulnerable copy for weeks. For anyone running their own server, it is the second patch-and-restart job this month after the NGINX flaws.

brotlinode.jspythongooglevulnerabilitybunopenaiimpervalinuxserversbrowsersopen source

Read also