# Brotli CVE-2026-111497: why AI agents that fetch URLs should be patched first

> CVE-2026-111497 is a critical Brotli decoder flaw now in CISA KEV. Why URL-fetching AI agents are exposed, fixed versions, and how to find hidden copies.

- Published: 2026-10-29
- Author: Enforster AI (https://enforster.ai)
- Category: AI Security
- Tags: AI Security, Supply Chain, Security Operations, Engineering, LLM
- Canonical URL: https://blog.enforster.ai/brotli-cve-2026-111497-ai-agents-url-fetching

## Key takeaways

- CVE-2026-111497 is an out-of-bounds write in the Google Brotli C decoder, versions 1.0.3 through 1.2.0, rated CVSS v4 9.2, that a crafted compressed stream can turn into memory disclosure, a crash, or code execution.
- CISA added CVE-2026-111497 to its Known Exploited Vulnerabilities catalog on October 27, 2026, with a remediation due date of November 10, 2026 for federal agencies.
- Python's urllib3, requests, aiohttp, and httpx with the brotli extra, and Node's built-in fetch, decode Brotli responses automatically, so code that never mentions Brotli can still reach the vulnerable decoder.
- An AI agent with a web-fetch or browsing tool lets anyone who can influence its prompt choose the server it downloads from, which turns the outbound path of this bug into a remote trigger.
- Fixed versions include Brotli 1.0.10, 1.1.1, and 1.2.1, Python brotli 1.2.1, brotlicffi 1.2.1.0, and Node.js 22.23.4, 24.22.1, and 26.12.1; container images and bundled copies stay vulnerable until rebuilt.

---

CVE-2026-111497 is a critical out-of-bounds write in the Google Brotli decoder that a crafted compressed stream can turn into memory disclosure, a crash, or remote code execution. It sits underneath Node.js, Python HTTP clients, Envoy, Istio, Bun, and many other products, and CISA added it to the Known Exploited Vulnerabilities catalog on October 27, 2026. Patch the decoder everywhere, but start with services that download content from servers you do not control, and AI agents with web-fetch tools are near the top of that list.

This guide explains why agents are a natural trigger, which versions fix the bug, and how to find copies of Brotli that a normal dependency scan misses. It reflects the advisories as of October 29, 2026.

## What is CVE-2026-111497?

The [GitHub advisory GHSA-9v8h-qqgm-4m35](https://github.com/advisories/GHSA-9v8h-qqgm-4m35) describes a buffer overflow in the Brotli decoder (`c/dec/decode.c`) in Google Brotli 1.0.3 through 1.2.0, on all platforms, rated critical at CVSS v4 9.2 with no privileges or user interaction required. It is classed as CWE-252, unchecked return value, and CISA also lists CWE-787, out-of-bounds write.

The [Node.js October 2026 security release](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases) gives the clearest description of the mechanism. An invalid block switch was reported as "needs more input" instead of a permanent format error, so the streaming decoder kept appending input bytes to an eight-byte internal buffer. Anyone who can supply Brotli data that an application decompresses can corrupt process memory.

The bug was reported by Khai Tran and Sylvie Mayer of OpenAI Codex Security, according to the Node.js release. [Wiz](https://www.wiz.io/blog/cve-2026-111497-brotli-rce-node-js) reports that Ron Masas of the Imperva Red Team demonstrated exploitability against unpatched Node.js. The same bug circulates under several nicknames, including Node2Shell, HTTP2Shell, and Broccoli2Shell.

> **KEV deadline:**
>
> CISA's KEV entry for CVE-2026-111497 was added on October 27, 2026 with a due date of November 10, 2026 for federal agencies under BOD 26-04. Even if you are not bound by that directive, treat it as a signal that the bug is being used.

## Why are AI agents especially exposed?

Most HTTP clients decode compressed responses for you. [Aikido's analysis](https://www.aikido.dev/blog/python-packages-vulnerable-node2shell-brotli-cve-2026-111497) lists the Python clients that use the vulnerable packages automatically when they are installed: urllib3 and therefore requests, aiohttp, httpx with its brotli extra, and Scrapy or anything built on them. On the Node side, the built-in `fetch` (Undici) pushes a `zlib.createBrotliDecompress` stream for any response with `Content-Encoding: br`, which is exactly the `node:zlib` path the Node.js advisory names.

Aikido also points out that changing `Accept-Encoding` does not protect you, because a malicious server can send Brotli whether or not the client asked for it.

Put that next to how agents are built. A browsing tool, a "summarize this link" feature, a RAG crawler, or a research agent all download content from URLs that are chosen at runtime. In many designs the URL comes from the model, and the model takes its cue from user input, retrieved documents, or earlier web pages. That means anyone who can get text in front of the agent can pick the server it fetches from. We covered why that kind of influence cannot be filtered out at the prompt layer in [prompt injection is an access-control problem](https://blog.enforster.ai/prompt-injection-is-an-access-control-problem).

The result is a short chain:

1. An attacker plants an instruction or a link in content the agent will read.
2. The agent calls its fetch tool on the attacker's URL.
3. The attacker's server replies with a crafted `br` response.
4. The HTTP client decodes it in the agent's process, before any of your code inspects the body.

Step 4 runs inside whatever holds the agent's credentials: model API keys, tool tokens, sometimes cloud roles. That makes the agent worker a higher-value target than a typical stateless web front end.

> **Inbound matters too:**
>
> The outbound path is the agent-specific one, but Aikido also describes an inbound path: frameworks or middleware that decode request bodies sent with Content-Encoding: br. Proxies and gateways in front of model endpoints, such as Envoy or Istio, are on the affected list as well.

## Which versions fix CVE-2026-111497?

Google released Brotli 1.2.1 on October 21, 2026 with the security fix. The GitHub advisory names 1.0.10, 1.1.1, and 1.2.1 as the fixed releases for each branch. Downstream fixes reported in the advisories and in Wiz's summary:

| Component | Fixed version |
| --- | --- |
| Google Brotli (libbrotli) | 1.0.10, 1.1.1, 1.2.1 |
| Python `brotli` | 1.2.1 |
| Python `brotlicffi` | 1.2.1.0 |
| Node.js | 22.23.4, 24.22.1, 26.12.1 |
| Bun | 1.4.4 |
| Envoy | 1.36.12, 1.37.8, 1.38.6, 1.39.3, 1.40.0 |
| Istio | 1.29.9, 1.30.6, 1.31.2 |
| Go `andybalholm/brotli` | v1.2.7 |

The Node.js advisory notes that end-of-life Node.js lines are affected too and get no fix, so move them to a supported release. Aikido reports that brotli4j users on Java and Netty stacks should upgrade to 1.24.0, and that .NET self-contained apps need a rebuild because updating the host runtime does not update a bundled copy.

## How do you find every copy of Brotli?

Brotli is usually a transitive dependency or a statically linked library, so a manifest that never names it can still ship it. Work through each layer.

### Python environments and images

```bash
# Which Brotli packages are installed, and at what version?
pip show Brotli brotlicffi

# What pulled them in?
pipdeptree -r -p Brotli

# Lockfiles across the repo
grep -ri brotli poetry.lock uv.lock requirements*.txt 2>/dev/null
```

Run these inside each container image and virtual environment, including CI runners and notebook servers, not only on a developer laptop. Aikido's advice applies directly: an image built on a vulnerable version stays vulnerable until you rebuild it.

### Node.js and Bun

```bash
node --version          # must be 22.23.4, 24.22.1, 26.12.1 or later on that line
bun --version           # must be 1.4.4 or later
```

Brotli is compiled into the Node.js binary, so `npm update` does nothing here. Upgrade the runtime, update the base image tag, rebuild, and redeploy. Serverless functions pin a runtime version too, so check the configured runtime for each function.

### Gateways, proxies, and bundled copies

Check the versions of Envoy, Istio, and any API or AI gateway built on them. For vendor products, libcurl builds, and self-contained binaries, look for the vendor's advisory; a statically linked decoder is fixed only by a new build.

## What should you do first?

Order the work by who controls the bytes your decoder sees.

1. **Agents and tools that fetch arbitrary URLs.** Browsing tools, link unfurlers, crawlers, webhook consumers, and any "fetch this URL" feature. Patch the runtime or package and redeploy today.
2. **Internet-facing services that accept compressed request bodies,** and the gateways in front of them.
3. **Internal services and batch jobs** that only talk to systems you operate.
4. **Developer machines and CI,** where coding agents and test suites also fetch remote content.

If you cannot patch an agent worker right away, the Python-specific stopgap from Aikido is to uninstall `Brotli` and `brotlicffi`, which removes the vulnerable decoder from Python clients but may cause errors with servers that send Brotli anyway. Rejecting `br`-encoded requests at the edge reduces inbound exposure only; it does nothing for responses your agent downloads. Neither replaces patching.

> **Isolate the fetcher:**
>
> Longer term, run web-fetch tools in a separate, low-privilege process or sandbox that holds no API keys or cloud credentials, and pass only extracted text back to the agent. A memory-safety bug in a parser then compromises a disposable worker, not the agent that holds your secrets.

That isolation is the same principle we applied to model responses in [LLM output is untrusted input](https://blog.enforster.ai/llm-output-is-untrusted-input): data an attacker can shape should be parsed where a failure is cheap. This bug simply moves the untrusted parser one layer lower, into the compression library.

## What should you watch for?

- **Crashes in agent workers or HTTP-heavy services** with memory corruption signatures shortly after fetching external URLs.
- **Outbound fetches to newly registered or unusual domains** that originate from agent tool calls, especially when the response carries `Content-Encoding: br`.
- **Unexpected child processes or network connections** from runtime processes such as `node` or `python` that normally only serve requests.

Wiz recommends reviewing WAF, application, and network logs for suspicious Brotli-compressed traffic and anomalous process behavior. For a comparable patch-and-verify workflow on a recent engine-level bug, see our guide to [PHP2Shell](https://blog.enforster.ai/php2shell-cve-2026-109618-cve-2026-109619).

## Key points for risk owners

The fix itself is simple: newer versions of a compression library. The hard part is reach. Brotli sits in runtimes, HTTP clients, and proxies that rarely appear on an application's dependency list, and the AI features most likely to reach it are the ones designed to read whatever the internet sends back. Track this as a fleet-wide runtime and image update, confirm the patched versions are actually running after redeploy, and treat any agent that fetches attacker-chosen URLs as an internet-facing service.
