Brotli CVE-2026-111497 is now on CISA's exploited list, and you probably run more copies than you think
A flaw in Google's Brotli decoder can turn a crafted compressed stream into a memory write, and CISA lists it as exploited. Here's where Brotli hides beyond Node.js, which versions fix it, and the patch order that catches bundled copies.
part 10 of 10 · Platform releases, explained from scratchthe ideaThe bug lives in a shared decoder, so every copy needs patching.
after reading, you can- Find where Brotli actually sits in a stack, well beyond Node.js, down to Python wheels and firewalls
- Match each product to its fixed build, and catch containers still running old code on a patched host
- Plan the patch order so services that unpack data from strangers go first
BrotlidefinitionGoogle's compression format, the one behind Content-Encoding: br. Lots of software copies Google's C library for it instead of writing its own. is the compression code that unpacks a lot of web traffic, and CISA now lists a flaw in it as exploited. Anything that decodes Brotli with Google's library from 1.0.3 to 1.2.0 needs the fixed build, and US federal agencies have until November 10. Node.js is the best-known case, but the same decoder sits inside Python packages, .NET, proxies and some firewalls.
A bad compressed file can break the code that unpacks it, and that code is in more places than you think.
Websites and apps squeeze data before sending it and unpack it on arrival, and Brotli is one of the common ways to do that. Google's Brotli library had a bug in the unpacking step. Feed it a deliberately broken stream and it writes past the end of a small memory buffer. At best the program crashes. At worst, researchers showed, it runs code the attacker hid in the data. The library is copied into hundreds of products, so one fix upstream turns into dozens of separate updates downstream.
It's like a mailroom sorter nobody ever taught what a bad label looks like. When one turned up, it assumed more mail was on the way and kept stacking letters into a slot that holds eight, and the overflow jammed the controls next door. The patched sorter just sends that parcel back.
- Teams running any Node.js line
- Python apps with Brotli installed
- .NET apps that unpack Brotli
- Envoy, Istio and other proxy users
- Palo Alto firewalls inspecting traffic
- Anyone shipping containers
Why it matters to you
Most patch news is about one product. This one is about a part that many products share, so the hard work is finding where it hides. A server you patched last week can still carry an old Brotli inside a Node binary, a Python wheel or a container image built in August.
CISA added the flaw to its Known Exploited Vulnerabilities catalog on October 27, which is where it lists bugs it has evidence of attacks against. CISA's own notes call Brotli an open-source component that could be used by different products, and that's the real warning. Palo Alto Networks says it isn't aware of any malicious exploitation, so read the KEVdefinitionCISA's list of flaws it has seen attacked. Once a bug is on it, US federal agencies get a deadline. It's a sensible list for anyone else to patch from first. listing as being about Brotli in general, not about any one vendor.
How bad it gets depends on what your software does with compressed data from outside. Imperva's red team ran their own code on the official Node.js 24.22.0 image for Linux arm64, using a Brotli body sent to Express and a Brotli response pulled in by fetch(). It took them several attempts. Red Hat says hardening such as ASLR makes code execution harder on its systems, though it still expects crashes.
-
01 Crafted compressed data
Someone gets Brotli data in front of your software. Usually that's a request body, a response your app fetched, or an uploaded file.
-
02 An impossible block switch
The stream asks the decoder to switch to a block type it never declared. A correct decoder would stop right there.
-
03 Read as 'need more input'
The old code treated that as a pause and kept appending bytes to an eight-byte internal buffer, past its end.
-
04 Memory corrupted
Nearby decoder data gets overwritten. That can crash the process, leak memory or, with work, run the attacker's code.
For engineers: the weakness is filed as CWE-252, an unchecked return value, leading to CWE-787, an out-of-bounds write. Before the fix, DecodeBlockTypeAndLength() returned a plain true or false, so callers couldn't tell a broken stream from one that had simply run out of input. The fast decode path threw the result away. Google's fix, commit 0ed4268 ("Detect and report invalid stream earlier"), makes the function return an error code and adds a new one, BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH, so decoding stops on both paths.
| Who | Rating | Why it differs |
|---|---|---|
| Google (CVE issuer), GitHub advisory | 9.2 Critical (CVSS 4.0) | Network, no login, no user action, though an attack requirement is present |
| Node.js | High | Rated for Node's bundled decoder |
| Microsoft (.NET) | 8.1 High (CVSS 3.1) | Brotli decompression is off by default in ASP.NET Core and HttpClient |
| Red Hat | Important | Hardening on RHEL makes reliable code execution harder |
| Ubuntu | Medium priority | Ubuntu's own triage of the brotli package |
| Palo Alto Networks | 9.2 Critical, urgency moderate | Only firewalls with Brotli inspection and TLS decryption turned on |
Don't let a medium label on a Linux package slow you down. A researcher on the oss-security mailing list warned on October 23 that people might read the Node.js advisory and decide they had nothing to worry about because they don't run Node. He also questioned Ubuntu's medium rating. The library is the problem, and it's in a lot of places.
What got fixed, and where the fix has to land
Google released three fixed builds on the same day, one for each 1.x line people still use, so nobody has to move to a newer line. The hard part is that most of your software doesn't use Google's build directly. Each product that copied Brotli in has to ship its own update, and you have to install each one.
Where the fix has shipped so far
The library itself, released October 21. Anything built from 1.0.3 to 1.2.0 needs one of these, or a vendor build that includes the change.
Official Node.js builds bundle their own Brotli, so the system library doesn't help them. Older Node lines are end of life and get nothing.
Both PyPI packages compile the same C decoder. requests, aiohttp and other clients use them on their own whenever they're installed.
Also 11.0 RC3. Apps are exposed only if they turn on Brotli decompression or call BrotliStream or BrotliDecoder on outside data. .NET Framework isn't affected.
Only deployments with the Brotli decompressor configured are exposed. Istio and other Envoy-based meshes pick it up through their own releases.
Firewalls are exposed only with Brotli inspection and TLS decryption on, and inspection is off by default from 11.2.4. Palo Alto says the management interface isn't affected.
Ubuntu 22.04, 24.04 and 26.04, Debian 12 and 13 and Red Hat have patched libbrotli. Programs that link it still need a restart.
If you're on Idira SaaS, the old CyberArk cloud services, Palo Alto patched it for you and there's nothing to do. Self-hosted Idira isn't affected, it says.
| What you run | Fixed in | Watch out for |
|---|---|---|
| Google Brotli C library | 1.0.10, 1.1.1 or 1.2.1 | Vendored copies inside other projects need their own update |
| Node.js 22 / 24 / 26 | 22.23.4 / 24.22.1 / 26.12.1 | Node 20 and older lines get no fix. Check node -p process.versions.brotli |
| Python Brotli / brotlicffi (PyPI) | 1.2.1 / 1.2.1.0 | Update the lockfile too, or the next build reinstalls the old one |
| .NET 8 / 9 / 10 | 8.0.33 / 9.0.22 / 10.0.14 | Self-contained and NativeAOT apps need a rebuild, not only a runtime install |
| Envoy | 1.40.0, 1.39.3, 1.38.6, 1.37.8 or 1.36.12 | Only matters if the Brotli decompressor filter is configured |
| PAN-OS 12.2 / 12.1 | 12.2.4-h1 / 12.1.4-h13, 12.1.7-h11, 12.1.10-h3 | Some hotfixes still had ETAs on October 28. PAN-OS 11.1 and 10.2 aren't affected |
| PAN-OS 11.2 | 11.2.4-h23, 11.2.7-h23, 11.2.10-h17, 11.2.13-h4, 11.2.16-h1 | 11.2.10-h16 fixes PHP2Shell only. You need -h17 for Brotli |
| Ubuntu libbrotli | 24.04: 1.1.0-2ubuntu0.1, 22.04: 1.0.9-2ubuntu0.1 | 20.04 and older still said 'needs evaluation' on October 28 |
| Debian libbrotli | 12: 1.0.9-2+deb12u1, 13: 1.1.0-2+deb13u1 | Debian says its nodejs packages use the system library and rates them unimportant, so the libbrotli update is the fix |
From a quiet code change to the KEV list
- Feb 2026The code change enters Brotli
The commit that becomes the fix is dated February 27, months before it was called a security fix. Some projects picked it up without knowing.
- Oct 21, 2026Brotli 1.0.10, 1.1.1, 1.2.1 and Node.js fixes
- Oct 22, 2026CVE out, PyPI Brotli and brotlicffi fixed
- Oct 23, 2026Envoy fixes; GitHub adds the PyPI packages
- Oct 25, 2026.NET 8.0.33, 9.0.22 and 10.0.14
- Oct 26, 2026Palo Alto confirms PAN-OS exposure
Palo Alto lists affected versions with hotfix dates and an inspection workaround. The first hotfixes ship October 27.
- Oct 27, 2026CISA adds it to KEV
- Nov 10, 2026CISA's federal due date
The February date explains something odd in the vendor lists. A few projects, MuPDF according to an independent tracker and Ghostscript according to a post on oss-security, pulled in the change before anyone knew it mattered, so their recent builds were fixed early. Others still bundle the old decoder. That tracker listed DuckDB, the bundled Apache Arrow build, p7zip and 7-Zip-zstd as unpatched on October 27, mostly through Parquet files and archives a user opens.
Some paths are easy to miss. A researcher on oss-security pointed out on October 26 that git's HTTPS transport is exposed too, when libcurl is built with Brotli support, which he says most distributions do. So a build server cloning from a hostile mirror counts. On those systems the distribution's libbrotli update covers git, once nothing still has the old library loaded.
What to do now
What to do now, by who you are
- Ask IT for a list of systems that unpack outside data with Brotli, and a patch date for each one.
- Ask your hosting, SaaS and firewall vendors for their CVE-2026-111497 status in writing.
- If you sell to US federal agencies, expect questions about November 10. Have an answer ready.
- Ask who checks the logs afterwards. Patching closes the gap but says nothing about last week.
- Update libbrotli from your distribution, then restart everything that has it loaded.
- Move Node.js to 22.23.4, 24.22.1 or 26.12.1 on servers, build agents and serverless runtimes.
- Check Palo Alto firewalls with show system setting brotli. Where inspection is on, hotfix them or switch it off for now.
- Proxies that decode br come before internal systems. Envoy needs its own release, and so does a mesh built on it.
- Search lockfiles for Brotli and brotlicffi, raise them to 1.2.1 and 1.2.1.0, and regenerate the lock.
- Move .NET to 8.0.33, 9.0.22 or 10.0.14, and rebuild self-contained and NativeAOT apps.
- Rebuild every container image on a patched base. A new tag on an old base changes nothing.
- Find code that unpacks Brotli it didn't create: fetch() responses, request bodies, uploads, queue messages.
- Treat this as a component hunt. Search SBOMs and image scans for brotli, libbrotlidec and brotlicffi.
- Don't trust a quiet scanner. Early on, Python scanners missed the PyPI packages, and vendored copies rarely show.
- Look for decoder crashes and unexpected restarts in Node, Python and proxy processes since October 21.
- Track vendor statements for appliances and SaaS you can't patch yourself.
If you only have an hour, start with services that unpack data from the internet: public APIs that accept compressed bodies, crawlers and link previewers, webhooks and anything that imports from a URL. Imperva showed both directions work, data coming in and data your app goes out and fetches. A WAF can catch the first one. Nothing in front of your app sees the second.
# example output, with made-up versions. Run these on every host and inside every image, because each can differ node -p "process.version + ' brotli ' + process.versions.brotli" # Node's own copy, which is the one that counts v24.22.0 brotli 1.2.0 pip show Brotli brotlicffi | grep -E 'Name|Version' # run it in each virtualenv, since they don't share packages Name: Brotli Version: 1.2.0 dpkg -l | grep -i brotli ii libbrotli1:amd64 1.1.0-2ubuntu0.1 sudo grep -l brotlidec /proc/*/maps 2>/dev/null /proc/2214/maps # The package is patched but process 2214 still has the old library loaded. Restart it
A patch order that covers the hidden copies
- 01Build the list
Pull every place Brotli lives: distribution packages, Node versions, Python lockfiles, .NET runtimes, proxies, firewalls and container images. SBOMs help, but check images directly too.
- 02Rank by who sends the data
Anything that unpacks data from the internet or from partners goes first. Internal batch jobs on trusted files can follow.
- 03Shrink exposure while you wait
Reject Content-Encoding: br request bodies at the proxy or WAF where your apps don't need them. On PAN-OS, disable Brotli inspection until the hotfix is in.
- 04Patch and restart
Update the library or runtime, then restart processes and rebuild images. Pin the new versions in lockfiles and Dockerfiles so the next build doesn't undo it.
- 05Prove it
Read the version back from running processes and deployed images, not from the change ticket. Record the result against each system on the list.
Harden so the next one hurts less
This bug is a preview of how shared components fail. The flaw sat in one C file, and the fix took a week to reach a handful of big projects while others are still waiting. Teams that already knew where Brotli lived had a short week. Everyone else spent it searching.
Before: nobody knows where the decoder is
Old Brotli copies sit in images nobody has rebuilt in months. The app unpacks whatever it's sent or fetches, and nobody checks.
After: known, pinned and contained
Someone can find every Brotli copy from the SBOM. The edge drops compressed bodies on routes that don't need them, and the service only reads its own tables.
- No SBOM, so finding Brotli means asking every team
- Base images rebuilt when someone remembers
- Lockfiles float, so a rebuild can pull an old wheel back in
- The app's service account can read far more than the app needs
- Ask 'where do we run Brotli?' and someone answers from the SBOM in minutes
- Someone rebuilds base images every month, and again the day a bad CVE lands
- Pinned runtimes and lockfiles, updated by pull request
- Each service has its own login and only sees its own tables. One bad request can't reach the rest
- The edge only accepts compressed request bodies on routes that need them
Two of these do most of the work. An SBOMdefinitionA software bill of materials: a list of the components inside an application or image. It lets you search for a library like Brotli instead of asking every team. you can search turns 'are we affected?' from a week of emails into an afternoon. A scoped identity limits what an attacker gets if a decoder bug does turn into code execution, because the process can only reach what it was meant to. Our post on the PHP2Shell and Node.js releases walks through scoping the app account in more detail.
If you've been breached
If you find signs someone used this
Nobody has published indicators of compromise for this flaw. Imperva suggests treating decoder errors and unexpected process exits as leads to check, not proof. Work in order and keep evidence before you change anything.
- 01Containfirst hour
- Take the suspect service out of rotation and snapshot the host or container before restarting it.
- Block its outbound traffic except to what the investigation needs.
- Copy logs off the box: application, proxy, WAF and crash or core dumps.
- 02Investigatefirst days
- Line up crashes in Node, Python, .NET or proxy processes since October 21 with the requests or fetches just before them.
- Look for child processes, new files or outbound connections from the service that nobody can explain.
- Check what the service's credentials did: database queries, cloud API calls and secret reads.
- 03Rebuilddays 1 to 3
- Rebuild hosts and images on patched versions instead of cleaning them in place.
- Redeploy from source you trust. Pin the lockfiles to fixed Brotli versions first, or the rebuild just brings the old one back.
- 04Rotateafter rebuild
- Change every secret the process could read. That usually means API keys, database passwords, tokens and signing keys.
- Do it after the rebuild, so an attacker still inside can't read the new values.
- 05Report and learnfirst weeks
- Bring in legal early. Breach notice rules depend on the data and your state or sector.
- Ring the insurer early and ask what the policy needs from you before anyone hires outside help. Customers hear from you once you know their data was reachable.
- Add the gaps you found to the SBOM and patch process.
Memory bugs leave little behind. A crash in a decoder can be a failed attempt or a broken file from a partner, and a successful attempt might not crash anything. That's why the rotation step matters even when the evidence is thin.
What this could look like: three typical setups
What this could look like: three typical setups
- the setup
- A retailer's order API runs on Node 24.22.0 in Kubernetes and takes compressed JSON from partners through Express 5. Ops patched the host OS on Monday and closed the ticket.
- what happens
- The host patch did nothing for the app. Node bundles its own Brotli, so every pod still runs the old decoder, and any partner or attacker who can post to the API can reach it.
- what to do
- Rebuild the image on node:24.22.1, roll the pods and check process.versions.brotli in each one. Until then, reject br bodies at the ingress on routes that don't need them.
- the setup
- A research team runs a Python crawler on requests and aiohttp that pulls pages from thousands of sites. Brotli 1.2.0 came in as a dependency, and nobody imports it directly.
- what happens
- Any site the crawler visits can send a Brotli response, and the HTTP client unpacks it on its own. A WAF in front of the crawler never sees this traffic, because the crawler started the request.
- what to do
- Raise Brotli to 1.2.1 in the lockfile and rebuild. If that has to wait, uninstall Brotli so the clients fall back to gzip, and remove any extra that would pull it back in.
- the setup
- A bank decrypts outbound web traffic on PA-Series firewalls running PAN-OS 11.2.10-h16, with Brotli inspection turned on so the firewall can scan compressed pages.
- what happens
- The firewall unpacks Brotli from any website a user visits, so the box doing the inspecting is the one exposed. The team thought -h16 covered it, but that hotfix only fixes PHP2Shell.
- what to do
- Move to 11.2.10-h17. Until then, run set system setting brotli-encoding disable and confirm show system setting brotli says Enabled: no.
These three are made up, and none is a real incident or a Cohash client. Each version number in them comes from the vendor pages behind this post.
How Cohash helps
We help teams find shared components like Brotli across images, runtimes and appliances, patch them in an order that keeps services up, and scope the identities those services run under. Our DevSecOps practice handles SBOMs and image rebuild pipelines, and our network security team works on firewall inspection settings. If you'd like a second pair of eyes on your exposure, start with an assessment.
What to take from this
- 01
The flaw is in Google's Brotli library, so it reaches well past Node.js. Check Python, .NET, proxies and firewalls too.
- 02
Fixed library lines are 1.0.10, 1.1.1 and 1.2.1. Products that bundle Brotli need their own update.
- 03
Restart processes and rebuild images after patching. An installed package doesn't fix a running service.
- 04
Patch whatever unpacks outside data first. Responses your own code fetches count, and a WAF won't see those.
- 05
On PAN-OS, 11.2.10-h16 isn't enough. Hotfix or turn off Brotli inspection.
- 06
Keep a searchable SBOM, so the next shared-library CVE takes an afternoon to scope.
01Am I affected by CVE-2026-111497?
You are if anything you run decodes Brotli with Google's library from 1.0.3 to 1.2.0, or a product that bundles it, on data someone else controls. Common cases are Node.js 22, 24 and 26 before the October fixes and end-of-life lines such as 20, 23 and 25, Python apps with Brotli or brotlicffi installed, .NET apps that turned on Brotli decompression, Envoy with the Brotli decompressor, and some PAN-OS firewalls.
02I don't use Node.js. Do I need to care?
Yes. The bug sits in Google's Brotli library, and Node.js just happens to be the best-known product that bundles it. The fixed-versions table above lists the others we checked. Search your inventory for Brotli itself, because the Node advisory won't tell you about the rest.
03Is CVE-2026-111497 being exploited?
CISA thinks so. It added the flaw to its Known Exploited Vulnerabilities catalog on October 27 with a federal due date of November 10. Palo Alto says it isn't aware of any malicious exploitation. Imperva has shown code execution on an official Node.js build, though it took several attempts.
04Which version fixes it?
It depends on what you run, and the fixed-versions table above has the full list. The library itself is fixed in 1.0.10, 1.1.1 and 1.2.1, and Node.js in 22.23.4, 24.22.1 and 26.12.1. For anything else, go by the vendor's own advisory, since each one ships its own build.
05I updated the package, but the scanner still flags it. What did I miss?
Running processes keep the old library until they restart, and container images keep whatever they were built with. Restart services, rebuild images on a patched base, and update lockfiles so the next build doesn't pull the old version back in.
06Is there a workaround if I can't patch yet?
Partly. You can reject Brotli request bodies at a proxy or WAF, uninstall the Python Brotli packages so clients fall back to gzip, remove Brotli from .NET decompression settings, or turn off Brotli inspection on PAN-OS. None of these covers every path, and Node.js lists no workaround, so plan to patch.
07Are browsers affected?
Chromium and Firefox were reported fixed before the public list of affected projects was made. Keep browsers on automatic updates and check managed fleets that pin old versions.
Three questions, about a minute
Pick an answer and we'll tell you if it's right, and why it is or isn't. The score stays in this browser.
-
Q1Your Ubuntu servers got the patched libbrotli package this morning. A Node 24.22.0 API runs in containers on them. Is the API fixed?
show the answer
B. No. Node bundles its own Brotli, so rebuild the image on 24.22.1 Containers don't use the host's library, and official Node.js builds ship their own copy of Brotli anyway. The image has to be rebuilt on a fixed Node release and redeployed.
-
Q2A Python crawler uses requests and has Brotli 1.2.0 installed as a dependency. Your WAF blocks br request bodies. Is the crawler covered?
show the answer
C. No. Responses it fetches are unpacked automatically, and the WAF never sees them HTTP clients such as urllib3 decode Brotli responses whenever the package is installed. The crawler starts those requests itself, so an inbound WAF rule can't help. Upgrade to 1.2.1.
-
Q3Your PA-Series firewalls run PAN-OS 11.2.10-h16 with TLS decryption and Brotli inspection on. What's the right move?
show the answer
A. Move to 11.2.10-h17, or disable Brotli inspection until you can Palo Alto says -h16 only fixes the PHP vulnerabilities and -h17 includes the Brotli fix. Until the hotfix is in, disabling Brotli inspection removes the exposed path.