Content-Encoding: br from sources you do not control, assume you are in scope and patch the Brotli version in your images and runtimes now.
What HTTP2Shell is
HTTP2Shell (and the earlier name Node2Shell) is the nickname for CVE-2026-111497, an out-of-bounds write in Google’s Brotli decoder. A crafted Brotli-compressed stream can write past the end of a buffer and corrupt a program’s memory. Depending on conditions, that leads to a crash, a memory leak, or execution of attacker-controlled code. Google is the CVE authority for Brotli; the CVE record rates it critical.
Two things make it dangerous in practice:
- No authentication required. The attacker only needs to get a malicious Brotli stream in front of a process that decodes it. That is the normal flow of the web.
- Brotli decoding is often automatic and invisible. HTTP clients and servers negotiate
Content-Encoding: brand decompress the body for you. If your code calls an outbound API, scrapes a URL, or accepts compressed uploads, you may be decoding attacker-influenced Brotli without a single line in your app that mentions Brotli.
The flaw was introduced in Brotli’s source in February 2026 and shipped as a security fix only in October, so a wide range of software picked it up in the meantime.
Why this is a cloud and container problem, not just a Node problem
The first framing was “a Node.js bug,” because Node bundles Brotli and patched it on 21 October. But the library is a shared dependency across the stack, which is exactly why the name changed to HTTP2Shell. Affected and already-patched software includes Node.js, Python, Bun, curl, Envoy, libbrotli, and brotlicffi, with more following.
For a team running workloads in the cloud, that breadth is the real story. Brotli does not live in one place you can point at. It is:
- Baked into container images - a base image or a language runtime in your
Dockerfilecan carry a vulnerablelibbrotliyou never chose explicitly. - Pulled in transitively - a dependency of a dependency, several layers down your lockfile, with no direct mention in your own manifest.
- Sitting in your ingress and service mesh - Envoy (and therefore a number of API gateways and mesh sidecars built on it) decodes Brotli. A proxy that terminates or inspects compressed traffic is a decoder too.
- Inside managed and third-party components you did not build, wherever they accept compressed input.
So “are we affected?” is not one check. It is an inventory question across your images, your runtimes, your proxies, and your dependency trees.
Who is affected
If any of the following decode Brotli from a source you do not fully control, treat them as in scope until you confirm the version:
- Application runtimes that fetch or receive compressed data - Node.js, Python, Bun, and others using an unpatched Brotli decoder
- Container images whose base layer or packages include
libbrotli/brotli1.0.3 through 1.2.0 - Proxies, ingress controllers, API gateways, and service-mesh sidecars built on Envoy
- CLI and build tooling that fetches over HTTP (for example curl) inside pipelines and images
- Any custom service that accepts Brotli-compressed uploads or decodes responses from remote servers
The vulnerable range is Brotli 1.0.3 through 1.2.0. The fixed releases are 1.0.10, 1.1.1, and 1.2.1 (all shipped 21 October 2026).
The fix: patch the Brotli your workloads actually run
There is no single package to bump, because Brotli reaches you through several channels. Work through them:
| Where Brotli lives | What to do |
|---|---|
| Node.js runtime | Update to a patched release (22.23.4, 24.22.1, or 26.12.1) and rebuild images that bundle Node. |
| Python / Bun / other runtimes | Update to the versions their maintainers shipped with the fix; rebuild and redeploy. |
| System library in images | Upgrade libbrotli to 1.0.10 / 1.1.1 / 1.2.1 in the base image, rebuild, and push a new image tag. |
| Envoy / proxies / mesh | Update to the patched Envoy build; roll the ingress controllers and sidecars that depend on it. |
| Transitive dependency | Regenerate lockfiles so the patched Brotli resolves, then rebuild. |
The operational sequence is the part teams get wrong under time pressure:
- Update the dependency or base image to a patched Brotli version.
- Rebuild the affected container images. Patching a running container is not enough; the vulnerable library is in the image, so the image has to change.
- Redeploy and restart so every running workload is on the patched runtime or library. A pod that was not rescheduled is still vulnerable.
- Verify the version actually in use by running workloads, not just the version in your manifest. Exec into a running container and check the resolved Brotli version where you can.
# Check the Brotli shared library version inside a running image/container
dpkg -l | grep -i brotli # Debian/Ubuntu base images
rpm -qa | grep -i brotli # RHEL/Amazon Linux base images
# Check Node's bundled version
node -e "console.log(process.versions.brotli ?? process.versions.node)"
If you cannot patch something immediately
Where a patch is not yet available for a component, or a rebuild/redeploy cannot happen this hour, the interim mitigation is to stop decoding untrusted Brotli: disable Brotli decoding on the exposed path until you can patch. At the edge, a web application firewall can help - Azure, for example, published WAF guidance for CVE-2026-111497 - by filtering or stripping Content-Encoding: br on inbound traffic. Treat that strictly as a stopgap: the fix is the patched library in your images, and the WAF only covers the paths it sits in front of, not internal service-to-service or outbound-fetch decoding.
What to do this week
- Inventory where Brotli decodes untrusted data. Application runtimes, container base images, Envoy-based proxies and meshes, build tooling, and any service accepting compressed input. Scan your images and lockfiles for
brotli/libbrotliin the 1.0.3-1.2.0 range. - Patch and rebuild. Bump runtimes, base-image libraries, and proxies to the fixed versions; regenerate lockfiles for transitive pulls; rebuild every affected image.
- Redeploy and restart. Roll the workloads so nothing is still running the old library. Confirm pods were actually replaced.
- Verify in running workloads. Check the resolved Brotli version where the code actually runs, and keep an eye on vendor advisories for components still awaiting a patch.
Not sure where Brotli is hiding in your stack?
We offer a free 30-minute sanity check: we help you inventory where your workloads decode Brotli - images, runtimes, proxies, and dependency trees - confirm what is patched, and plan the rebuild-and-redeploy safely. No commitment. See our Security & Compliance work or book a call below.
This is the second critical, unauthenticated RCE to cut across the ecosystem in a matter of days, after the PHP core flaws we covered in php2shell. The pattern is the same: a shared component deep in the stack, a trigger that never touches your application code, and a fix that is only real once the image is rebuilt and the workload redeployed. If you want a structured look at where your environment carries this kind of exposure, our Well-Architected Review covers exactly that.
Running cloud workloads and not sure if Brotli affects you?
Book a free 30-minute call. We'll help you find where your workloads decode Brotli, patch what can be patched, and get the rebuild and redeploy done safely.