New: Citizen Developer Security | Let everyone develop. Securely.

See how

Blog

node2shell / HTTP2Shell (CVE-2026-111497): What to patch and how to check if you’re exposed

10 MIN

node2shell (CVE-2026-111497): What to Patch and How to Find Exposed Services
Summarize with AI

Update, October 30, 2026: Added how to check if you’re exposed and answers to common questions. Some coverage calls this bug HTTP2Shell or Broccoli2Shell. It is the same CVE. On October 27, CISA added it to the Known Exploited Vulnerabilities catalog after confirming exploitation in the wild.

CVE-2026-111497, also called node2shell, HTTP2Shell or Broccoli2Shell, is an out-of-bounds write in the Brotli decoder that ships inside Node.js. A crafted Brotli stream can crash the process, leak memory or run code. The fix is Node.js 22.23.4, 24.22.1 or 26.12.1 and Bun 1.4.4, and the services to patch first are the ones that decompress Brotli data they do not control.

Update, October 26, 2026: .NET

On October 25 Microsoft released out-of-band .NET updates for CVE-2026-111497 in the copy of the Brotli decoder that .NET uses. Microsoft rates it Critical for .NET and Visual Studio and Important for PowerShell, with a CVSS 3.1 score of 8.1 (the 9.2 above is the CVSS 4.0 score). The issue is publicly disclosed. Microsoft reports no exploitation as of October 25 and assesses exploitation as more likely.

Product Fixed in
.NET 8 runtime 8.0.33, SDK 8.0.427 (4xx band) and 8.0.133 (1xx band)
.NET 9 runtime 9.0.22, SDK 9.0.320 (3xx band) and 9.0.123 (1xx band)
.NET 10 runtime 10.0.14, SDK 10.0.403 (4xx band) and 10.0.114 (1xx band)
.NET 11 preview 11.0.100-rc.3.26522.148 (RC3)
PowerShell 7.4, 7.5 and 7.6 7.4.22, 7.5.13 and 7.6.9
Visual Studio 2019 16.11, 2022 17.14 and 2026 18.11 16.11.61, 17.14.43 and 18.11.2
Visual Studio 2026 18.12 (Insiders) 18.12 Insiders 3

.NET Framework is not affected.

Brotli decompression is off by default in .NET and ASP.NET Core. An application is exposed only if it, or a library it uses, turns on one of these:

  • ASP.NET Core request decompression (AddRequestDecompression and UseRequestDecompression)
  • HttpClient automatic response decompression that includes Brotli (AutomaticDecompression set to Brotli or All)
  • Brotli decompression through the System.IO.Compression APIs (BrotliStream with CompressionMode.Decompress or BrotliDecoder)

What Cycode added. The node2shell items on the Threat Intelligence dashboard now also list Dockerfiles that pin a .NET 8, 9 or 10 aspnet, runtime or sdk image below the fixed versions and container images with a .NET 8, 9 or 10 runtime below 8.0.33, 9.0.22 or 10.0.14. Floating tags such as aspnet:8.0 are not listed from Dockerfiles, because a rebuild picks up the fix; images already built from them show up through the image check. Because the exposure is opt-in, a listed .NET image tells you which applications to check for the settings above.

What to do.

  • Update the .NET runtime to 8.0.33, 9.0.22 or 10.0.14 and the SDK to a fixed version in the table, then restart the applications that run on it.
  • Rebuild and republish self-contained applications. They carry their own runtime, which a .NET update on the host does not change.
  • Rebuild container images with the updated base image (docker build –pull). Images built from tags such as aspnet:8.0 before October 25 keep the old runtime until they are rebuilt.
  • Update PowerShell and Visual Studio to the versions in the table.
  • Search your .NET code and dependencies for the decompression settings above to find applications that are exposed.

What Happened

The bug is in Google’s Brotli C library, which Node.js and Bun bundle. A stream that declares a single block type and then switches blocks was not rejected, so decoding continued in an invalid state and wrote past a buffer (CWE-787, CWE-252). Khai Tran and Sylvie Mayer of OpenAI Codex Security found and reported it to Node.js. Google, the CNA, scored it 9.2 Critical under CVSS 4.0, and Node.js rates it High. The Node.js advisory states that the bug permits remote code execution. Code execution has been demonstrated publicly on the official Node.js 24.22.0 arm64 image, and a public proof of concept exists. On October 27, CISA added the CVE to its Known Exploited Vulnerabilities catalog after confirming exploitation in the wild, and gave US federal agencies until November 10 to patch.

Date Event
Oct 27, 2026 CISA adds CVE-2026-111497 to the Known Exploited Vulnerabilities catalog.
Oct 22, 2026 CVE published. Code execution demonstrated publicly on Node.js 24.22.0. Bun 1.4.4 released with the fixed Brotli library.
Oct 21, 2026 Node.js releases 22.23.4, 24.22.1 and 26.12.1. Brotli 1.0.10, 1.1.1 and 1.2.1 released.
Feb 27, 2026 Fix committed to the google/brotli repository, with no release or advisory at the time.
Shift to AI podcast hosted by Roland Cloutier. Listen nowShift to AI podcast hosted by Roland Cloutier. Listen nowShift to AI podcast hosted by Roland Cloutier. Listen now

Who Is Exposed

Exposure takes two conditions. The first is a Node.js or Bun runtime below the fixed version, whether it sits in a container base image, on a build host or on a server. The bug is in the runtime, not in an npm package; the npm package named brotli is not the vulnerable component.

The second is a path for attacker data to reach the decoder. The Node.js advisory frames it as Brotli data that an application decompresses with node:zlib: zlib.brotliDecompress, brotliDecompressSync, createBrotliDecompress, or a library that calls them for you. A bare http server does not decode Brotli request bodies.

In Express 5 and body-parser 2.x, json(), urlencoded(), text() and raw() all decode Brotli request bodies. So do the Koa body parsers (koa-bodyparser, @koa/bodyparser, koa-body, co-body) and @fastify/compress with request decompression. The built-in fetch() decodes Brotli responses, so code that fetches user-supplied URLs is also exposed. Express 4 and body-parser 1.x do not decode Brotli request bodies.

Python is affected too. GitHub advisory GHSA-9v8h-qqgm-4m35 covers the PyPI packages brotli and brotlicffi, which bundle the same decoder.

Affected and Fixed Versions

Node.js lists no workaround, so upgrading is the fix. End-of-life Node.js lines get no patch.

Component Affected Fixed in
Node.js 26.x below 26.12.1 26.12.1
Node.js 24.x below 24.22.1 24.22.1
Node.js 22.x below 22.23.4 22.23.4
Node.js 20.x and other end-of-life lines all releases that bundle Brotli none; move to a supported line
Bun below 1.4.4 1.4.4
Google Brotli library 1.0.3 to 1.0.9, 1.1.0, 1.2.0 1.0.10, 1.1.1, 1.2.1
PyPI package Affected Fixed in
brotli 1.0.3 to below 1.2.1 1.2.1
brotlicffi 1.0.3 to below 1.2.1.0 1.2.1.0
See Cycode in action. Book a demoSee Cycode in action. Book a demoSee Cycode in action. Book a demo

How to Check If You’re Exposed

Exposure takes two things: a vulnerable runtime or library, and a path for attacker data to reach the Brotli decoder. Check both.

  1. Check the runtime version. Run node -v and bun --version on servers, build hosts and inside running containers. Node.js below 22.23.4, 24.22.1 or 26.12.1, any end-of-life line, or Bun below 1.4.4 is vulnerable. Check the base image tags in your Dockerfiles too. Images pinned by digest need an image scan, because the tag doesn’t show the version.
  2. Check Python environments. Run pip show brotli brotlicffi. brotli below 1.2.1 or brotlicffi below 1.2.1.0 bundles the vulnerable decoder. Remember that requests, httpx and aiohttp use it whenever it’s installed.
  3. Check .NET. A .NET 8, 9 or 10 runtime below 8.0.33, 9.0.22 or 10.0.14 is affected, but only applications that turn on Brotli decompression are exposed (see the settings in the update above).
  4. Look for a path to the decoder. Express 5, body-parser 2.x, the Koa body parsers, @fastify/compress with request decompression, fetch() of user-supplied URLs or direct node:zlib Brotli calls. A service that has one of these and a vulnerable runtime goes to the top of the list.
  5. Check proxies. Envoy and Istio are exposed only when the Brotli decompressor is turned on.

About PoCs and scanners. A public proof of concept exists, and code execution has been shown on the official Node.js 24.22.0 arm64 image, and CISA confirmed exploitation in the wild on October 27. Start with a version check rather than a network scan: exposure depends on whether a service decodes Brotli, which a scan from outside may not reach. Only test systems you own or are authorized to test.

Beyond Node.js

Some coverage calls this HTTP2Shell or Broccoli2Shell. It is the same CVE-2026-111497, not a new vulnerability: any software that decodes untrusted Brotli data with an unpatched copy of the library is exposed.

  • Python clients. urllib3 (and so requests), httpx and aiohttp decode Brotli responses whenever brotli or brotlicffi is installed. Scrapy requires brotli, so every Scrapy install is exposed until brotli is upgraded. pip is not affected, because its bundled urllib3 has Brotli turned off. Code execution has not been shown for the Python packages.
  • Python servers. The aiohttp server decompresses Brotli request bodies by default when brotli is installed.
  • Other bindings. The Java library com.aayushatharva.brotli4j is fixed in 1.24.0 and the Ruby brotli gem in 0.9.1. curl_cffi bundles Brotli 1.2.0 and has no fixed release yet. Go’s cbrotli binding links the system library, so it needs a patched libbrotli.
  • Proxies. Envoy and Istio are affected only when the Brotli decompressor is enabled. Envoy is fixed in 1.40.0, 1.39.3, 1.38.6, 1.37.8 and 1.36.12, and Istio in 1.31.2, 1.30.6 and 1.29.9.
  • System libraries. curl decodes Brotli only with –compressed, through the libbrotli it links. Debian and Red Hat have shipped fixed brotli packages.

How Cycode Helps

The Threat Intelligence dashboard has five items for CVE-2026-111497. Each shows how many assets in your organization match and opens the query behind it in the Context Intelligence Graph. Every result links the asset to its repository, so the team that owns the fix is clear.

Services that accept Brotli bodies. This query finds a Dockerfile on a vulnerable Node.js or Bun image and, in the same directory, a dependency that decompresses Brotli request bodies: Express 5, body-parser 2, the Koa body parsers or @fastify/compress. Express 5 and body-parser 2 are the request paths shown to reach code execution in public research, so services that match both conditions are the ones to patch first. A match does not prove the route is reachable from outside, and the query does not see fetch() of user-supplied URLs or direct node:zlib use, so the runtime queries below still matter.

Dockerfiles on vulnerable runtimes. This query finds Dockerfiles that build on Node.js below 22.23.4, 24.22.1 or 26.12.1, on an end-of-life Node.js line or on Bun below 1.4.4. It flags digest-pinned Node.js and Bun images for review, because their version cannot be read from the tag. It also catches nvm install and NodeSource setup lines that install a vulnerable version.

Container images. Two more items look inside built images. One finds images whose Node.js or Bun runtime is below the fixed version. The other finds images that ship the distribution Brotli library in the affected range, for review against your distribution’s advisory, since distributions may backport the fix.

Code dependencies. A fifth item finds projects that depend on a library bundling the vulnerable decoder: brotli, brotlicffi and curl_cffi in Python, com.aayushatharva.brotli4j in Java and the Ruby brotli gem. It includes indirect dependencies, since HTTP clients often pull these in through other packages.

We tested each query against repositories with known-vulnerable and known-fixed versions before release.

First 24 Hours

  1. Find services that run Node.js below 22.23.4, 24.22.1 or 26.12.1, or Bun below 1.4.4, including base images and build hosts.
  2. Start with services that decompress request bodies (Express 5, body-parser 2, Koa body parsers or @fastify/compress), fetch user-supplied URLs or pass untrusted data to the node:zlib Brotli functions.
  3. Upgrade the runtime and rebuild the images, including standalone binaries built with bun build –compile. Replace end-of-life Node.js lines.
  4. Until the rebuild ships, reject Content-Encoding: br at the proxy or load balancer, or turn off inflation in your body parsers. Match br case-insensitively, including inside lists such as gzip, br. Turning off inflation rejects every compressed body, gzip included. Neither covers Brotli responses read by fetch().
  5. Check images for the distribution Brotli library and apply your distribution’s update.
Your complete Post-Mythos toolkit. Learn moreYour complete Post-Mythos toolkit. Learn moreYour complete Post-Mythos toolkit. Learn more

Sources

FAQ

Frequently asked questions

What is node2shell?

node2shell (CVE-2026-111497) is an out-of-bounds write in Google's Brotli decoder, which Node.js and Bun bundle. A crafted Brotli stream can crash the process, leak memory or run code. Google scored it 9.2 Critical under CVSS 4.0. The bug is in the runtime, not in an npm package, so upgrading Node.js or Bun is the fix.

Is HTTP2Shell the same as node2shell?

Yes. Some coverage calls it HTTP2Shell or Broccoli2Shell, but it is the same CVE-2026-111497, not a new vulnerability. Any software that decodes untrusted Brotli data with an unpatched copy of the library is exposed, including Node.js, Bun, Python's brotli and brotlicffi packages, .NET and Envoy or Istio with Brotli decompression turned on.

Is there a public PoC for CVE-2026-111497, and is it exploited?

Yes. A public proof of concept exists, and code execution has been demonstrated on the official Node.js 24.22.0 arm64 Docker image. On October 27, CISA added CVE-2026-111497 to its Known Exploited Vulnerabilities catalog, which confirms exploitation in the wild, and gave US federal agencies until November 10 to patch. Patch services that decode Brotli request bodies first.

Which versions fix node2shell?

Node.js 22.23.4, 24.22.1 and 26.12.1, and Bun 1.4.4. Google's Brotli library is fixed in 1.0.10, 1.1.1 and 1.2.1, and the Python packages in brotli 1.2.1 and brotlicffi 1.2.1.0. End-of-life Node.js lines, including 20.x, get no patch, so move them to a supported line.

Are Python and .NET affected by CVE-2026-111497?

Yes. The PyPI packages brotli and brotlicffi bundle the same decoder, and requests, httpx and aiohttp use it when installed. Microsoft shipped .NET fixes on October 25: runtime 8.0.33, 9.0.22 and 10.0.14. In .NET, Brotli decompression is off by default, so only applications that turn it on are exposed.

Do I need to restart or rebuild after patching?

Yes. Restart every process that runs the old runtime, and rebuild container images with the updated base image, including standalone binaries built with bun build --compile. Until the rebuild ships, you can reject Content-Encoding: br at the proxy, but that doesn't cover Brotli responses read by fetch().