Skip to content

Category: Vulnerabilities & Advisories

Broccoli2Shell: Critical Brotli Vulnerability and What to Do Now

Broccoli2Shell is a critical vulnerability in the decoder of the Brotli compression format. In the worst case, it can let attackers execute their own code using manipulated compressed data. Node.js, Python packages, .NET, and many other products that ship Google's Brotli decoder are affected. This article summarizes what is known, which versions are affected, and the measures recommended by vendors and CERTs.

Published Approx. 20 min read Author: Rootsektor Editorial Team

In short: Update Node.js to 22.23.4, 24.22.1, 26.12.1, or later; update the Python packages Brotli and brotlicffi to 1.2.1 and 1.2.1.0, respectively; and update the Brotli packages of your Linux distribution. Then restart every affected process and rebuild your container images. Also check .NET, firewalls with TLS inspection, and third-party products that ship Brotli. The EU Agency for Cybersecurity (ENISA) and the US agency CISA have listed the vulnerability as exploited since October 27, 2026. Information as of October 30, 2026 – we will update this article as the situation develops.

What is Broccoli2Shell?

Broccoli2Shell is one of several names for CVE-2026-111497, a vulnerability in the Brotli decoder. Brotli is a compression format that web servers and HTTP clients, among others, use to transfer data in compressed form, recognizable by the Content-Encoding: br header. The reference library, written in C, comes from Google and is built into runtimes, libraries, browsers, and other products (Red Hat RHSB-2026-015).

The Imperva Red Team published its analysis on October 22, 2026, under the name “Node2Shell” (Imperva). Because the vulnerability reaches far beyond Node.js, the names “HTTP2Shell,” “Brotli2Shell,” and “Broccoli2Shell” are now also in circulation (Aikido, Oct 23, 2026, Tenable, ELLIO). They all refer to the same vulnerability.

Google published the CVE record on October 22, 2026, and rated the vulnerability critical with a CVSS 4.0 score of 9.2 out of 10 (CVE-2026-111497). According to the description, it is a buffer overflow in the decoder of Brotli 1.0.3 through 1.2.0. With a crafted Brotli stream, an attacker can, over the network and without authentication, corrupt memory, disclose memory contents, crash the process, or potentially execute their own code – a form of remote code execution. According to the CVE record and Node.js, Khai Tran and Sylvie Mayer of OpenAI Codex Security found the vulnerability.

Ratings differ: the Node.js project rates the vulnerability “high” (Node.js security advisory, Oct 21, 2026). Red Hat rates it “Important,” arguing that a precisely crafted stream is required and that there is no public, reliable proof of concept for code execution (Red Hat).

The timeline:

  • February 27, 2026: The fix lands in the Brotli source code with the commit message “Detect and report invalid stream earlier.” and without any reference to a vulnerability (commit 0ed4268). No release follows for almost eight months.
  • October 21, 2026: Node.js releases versions 22.23.4, 24.22.1, and 26.12.1 (Node.js security advisory), and Google releases Brotli 1.0.10, 1.1.1, and 1.2.1 (Brotli release v1.2.1).
  • October 22, 2026: The CVE record is published, and Imperva describes code execution on an official Node.js image (Imperva). According to Aikido, an initial public proof-of-concept exploit works only against a deliberately weakened test build (Aikido, Oct 22, 2026).
  • October 25 and 26, 2026: Microsoft, Red Hat, Ubuntu, and Palo Alto Networks publish updates and advisories (details in the next section).
  • October 27, 2026: CISA adds the vulnerability to its catalog of actively exploited vulnerabilities (CISA, Oct 27, 2026).
  • October 28, 2026: Germany's Federal Office for Information Security (BSI) adds a reference to an exploit to its advisory and adjusts its rating (BSI WID-SEC-2026-4117).

Which software is affected?

The vulnerability lives in the Brotli library, not in a specific application. Any software that contains a vulnerable decoder and uses it to decompress data from untrusted sources is at risk (Red Hat RHSB-2026-015). This overview shows the status of the fixes:

  • Brotli (C library): Versions 1.0.3 through 1.2.0 are affected; the vulnerability is fixed in 1.0.10, 1.1.1, and 1.2.1 (CVE-2026-111497).
  • Node.js: fixed in 22.23.4, 24.22.1, and 26.12.1 and in all later versions (Node.js security advisory). Node.js 20, 23, and 25 have reached end of life and no longer receive updates (Node.js release schedule).
  • Python: The PyPI packages Brotli before 1.2.1 and brotlicffi before 1.2.1.0 ship the vulnerable decoder; the fixed versions are Brotli 1.2.1 and brotlicffi 1.2.1.0 (GHSA-9v8h-qqgm-4m35).
  • .NET: .NET 8, 9, and 10 before 8.0.33, 9.0.22, and 10.0.14, respectively, are affected, as are preview versions of .NET 11, but not the .NET Framework (Microsoft advisory, Oct 25, 2026). In its Security Update Guide, Microsoft also lists PowerShell 7 and several versions of Visual Studio as affected (Microsoft Security Update Guide).
  • Linux distributions: Debian, Ubuntu, and Red Hat have updated their Brotli packages, such as brotli, libbrotli1 (libbrotli at Red Hat), and python3-brotli (Debian, Ubuntu, Red Hat). For other distributions, check that distribution's own security notice.
  • Firewalls: PAN-OS 11.2, 12.1, and 12.2 are affected if both the inspection of Brotli-compressed traffic and TLS decryption are enabled. Brotli inspection is disabled by default as of PAN-OS 11.2.4. The management interface, PAN-OS 11.1 and 10.2, and Panorama are not affected. Hotfixes are available (Palo Alto Networks).
  • Other runtimes and proxies: Tenable also lists Bun, the official Windows builds of PHP, Envoy, and Istio as affected, the latter two only if a Brotli decompressor is configured. Fixed versions are available for all four (Tenable).
  • Browsers and email clients: According to Red Hat, Firefox and Thunderbird also ship their own copy of Brotli (Red Hat RHSB-2026-015). On RHEL, both are considered fixed as of version 140.10.0 (Red Hat).

Three points are easy to miss. First, distributions usually backport the fix under the old version number; Ubuntu 24.04, for example, ships it in the package brotli 1.1.0-2ubuntu0.1 (Ubuntu). What counts is therefore the full package version in the security notice, not the version range 1.0.3 through 1.2.0. Second, Node.js from distribution packages sometimes uses the system's Brotli library: on Debian and on Ubuntu 22.04 and later, the updated Brotli package is what matters. Red Hat, by contrast, ships Node.js 24 as the nodejs:24 module on RHEL 8 and 9 with its own copy of Brotli; fixed packages based on Node.js 24.22.1 have been available since October 29, 2026. For the nodejs:26 module on RHEL 9 and for .NET 8 on RHEL, however, no fix was available as of October 30, 2026 (Debian, Ubuntu, Red Hat).

Third, many projects embed their own bundled copies of Brotli, such as the ClickHouse and DuckDB databases, the JPEG XL library libjxl, and the UEFI development kit EDK II. None of these projects has published a release with the fix so far: ClickHouse and libjxl have applied it only in their source code, and DuckDB and EDK II have not applied it yet (own research, as of October 30, 2026). You can only find such copies if you know your dependencies, for example through an SBOM, a software bill of materials.

For context: only decompression is affected. If you use Brotli only to compress data, for example on a web server for its responses, you do not trigger the flaw (Aikido, Oct 23, 2026).

How the vulnerability works

A Brotli stream contains instructions that switch between different block types. This is exactly where the flaw lies: according to Node.js, the decoder did not report an invalid block switch as a format error but as if it merely needed more input. It therefore kept appending bytes to a small internal buffer and wrote past its end (Node.js security advisory). The fix detects the invalid stream earlier and aborts with a dedicated error code (commit 0ed4268). Normal, correctly generated Brotli data does not trigger the flaw; it takes a deliberately crafted stream (Red Hat RHSB-2026-015).

An application is vulnerable as soon as it decompresses Brotli data from a source an attacker controls. Advisories and analyses describe four attack paths:

  • Incoming requests: web applications that automatically decompress request bodies with Content-Encoding: br. In Node.js, Express 5 and body-parser 2.x do this by default with all parsers, including in the current body-parser version 2.4.0 (body-parser). According to Sysdig, Koa and Fastify with @fastify/compress also decompress Brotli bodies, whereas Express 4 with body-parser 1.x only handles gzip and deflate (Sysdig). A plain Node.js HTTP server does not decompress incoming data on its own (Imperva).
  • Fetched responses: applications that load content from third-party servers. The fetch() function built into Node.js automatically decompresses Brotli responses (Aikido, Oct 22, 2026); in Python, requests, urllib3, aiohttp, and HTTPX do the same as soon as Brotli or brotlicffi is installed (Requests documentation, OpenSourceMalware). According to ELLIO, features that fetch user-supplied URLs are particularly at risk, such as webhooks, link previews, and crawlers (ELLIO) – a pattern that also plays a role in SSRF. Adjusting the Accept-Encoding header is not enough: a malicious server can send Brotli anyway, and the client selects the decoder based on the response (Aikido, Oct 23, 2026).
  • Direct use: programs that decompress uploaded files or other input with Brotli themselves, for example via zlib.brotliDecompress() in Node.js or BrotliStream in .NET (Red Hat RHSB-2026-015, Microsoft advisory).
  • Network and security appliances: firewalls and proxies that decompress and inspect decrypted traffic, such as PAN-OS with Brotli inspection enabled (Palo Alto Networks).

The Imperva Red Team says it executed code embedded in Brotli data on the official, unmodified Node.js 24.22.0 image for Linux (arm64) – both through request bodies sent to an Express 5 application and through a response fetched with fetch(). This did not succeed on every attempt; Node.js 24.22.1 rejected the same input (Imperva). ELLIO also reproduced code execution on x86-64. According to ELLIO, failed attempts usually crash the affected process, which in itself means an outage of the service (ELLIO).

Is Broccoli2Shell already being exploited?

ENISA's European Union Vulnerability Database (EUVD) has listed the vulnerability as exploited since October 27, 2026 (EUVD-2026-108169). On the same day, the US agency CISA added it to its Known Exploited Vulnerabilities (KEV) catalog, citing evidence of active exploitation; it does not provide details about the attacks (CISA, Oct 27, 2026). The BSI rates its advisory on the Node.js vulnerabilities “critical” and on October 28, 2026, added a reference to an exploit for CVE-2026-111497 (BSI WID-SEC-2026-4117).

Here is what is publicly known: several proof-of-concept exploits have now been published; according to Tenable, at least one claims to execute code on Node.js 24.22.0 under narrow lab conditions (Tenable). In an update on October 26, 2026, ELLIO reported an attack attempt tailored to Node.js 24.22.0. It combined parts of public exploits with a custom final stage that did not succeed once in ELLIO's tests. ELLIO also observed a public exposure checker that specifically tested which servers decompress Brotli data; the company recommends treating the vulnerability as exploited (ELLIO). On October 29, 2026, Check Point reported broad, automated scanning in telemetry from its intrusion prevention system, some of it aimed at endpoints for uploads and data imports. Check Point considers suspicious payloads and HTTP 500 errors worth investigating but not evidence of a successful compromise (Check Point).

Confirmed successful breaches via Broccoli2Shell have not been publicly documented so far (own research, as of October 30, 2026). Palo Alto Networks is not aware of any malicious exploitation affecting its products (Palo Alto Networks). Sweden's CERT-SE nevertheless urges organizations to update quickly (CERT-SE); the Dutch NCSC (NCSC-NL) points to the security updates from Google and Node.js in its October 23, 2026, advisory (NCSC-NL). Assume that internet-facing services that decompress Brotli data are being actively searched for and attacked.

Immediate actions: update first

Only an update fully closes the vulnerability; according to Aikido, interim measures notably fail to protect against crafted responses from third-party servers (Aikido, Oct 22, 2026). Proceed in this order:

  1. Take inventory: Identify every Node.js runtime – on servers, CI runners, and developer machines, in container images, and in serverless functions. For an image, docker run --rm --entrypoint node <image> --version shows the version it actually contains without running the image's startup command. In Python environments, pip show Brotli brotlicffi and pipdeptree -r -p Brotli help, as does a search of your lockfiles (Aikido, Oct 22, 2026, Aikido, Oct 23, 2026). Searching for loaded libraries does not find statically linked copies of Brotli (Tanium). An up-to-date SBOM of your own software and of the products you purchase helps here.
  2. Check the right value: process.versions.brotli is not proof of a fix. Node.js only applied the fix and did not bump the version number of the bundled library (Node.js 24.22.1), so patched versions report the same Brotli version as vulnerable ones, for example 1.2.0 on Node.js 24 (ELLIO). What counts is node --version. If Node.js from your distribution's package uses the system's Brotli library, the version of the Brotli package matters as well (Red Hat).
  3. Update: Install Node.js 22.23.4, 24.22.1, 26.12.1, or later; Brotli 1.2.1 and brotlicffi 1.2.1.0 for Python; and the updated Brotli packages from your distribution. For .NET, the versions are 8.0.33, 9.0.22, or 10.0.14; for PAN-OS, the hotfix versions listed in the Palo Alto Networks advisory. Node.js 20, 23, and 25 no longer receive fixes; move to 22, 24, or 26.
  4. Restart and rebuild: An updated package on disk does not replace a decoder that a running process has already loaded (Tanium). Restart every affected service, and rebuild containers on patched base images (Red Hat RHSB-2026-015). With an image tag such as node:24, a rebuild may fall back on an image from the local cache, so run docker pull first and check the version in the running container (Sysdig). For .NET, self-contained applications must be rebuilt and NativeAOT applications republished (Microsoft advisory).
  5. Ask vendors and service providers: For appliances, hosted services, and third-party products, the update is up to the provider. Ask whether and when the systems will be patched, and follow the vendors' advisories.

If you cannot update immediately, the following interim measures reduce the risk for individual attack paths. They do not make a system secure:

  • Reject Brotli requests: Strip or block Content-Encoding: br on requests from untrusted clients at the reverse proxy or load balancer, as Red Hat recommends (Red Hat RHSB-2026-015). Detect br regardless of case and also within lists of multiple encodings (Aikido, Oct 23, 2026). A web application firewall can also handle this filtering. In Express 5, the parser option inflate: false rejects compressed bodies – but all of them, including gzip (body-parser).
  • Remove Brotli from Python environments: Where Brotli support is not needed, uninstall Brotli and brotlicffi, remove extras such as httpx[brotli], and regenerate your lockfiles (Aikido, Oct 23, 2026). The HTTP clients then fall back to gzip and deflate (OpenSourceMalware).
  • Use product settings: In .NET, remove br from the ASP.NET Core request decompression and DecompressionMethods.Brotli from the HttpClient settings (Microsoft advisory). In PAN-OS, disable Brotli inspection with set system setting brotli-encoding disable and verify it with show system setting brotli (Palo Alto Networks).
  • Limit outbound fetches: Ultimately, only the update protects against crafted responses from third-party servers. Until then, restrict which destinations your applications may fetch from, for example with an allowlist for webhooks (Tanium), and do not decompress untrusted data with the Brotli functions of node:zlib (Red Hat RHSB-2026-015).
  • Restrict exposure: Where no update is possible, CERT-SE advises restricting access with a firewall or disabling Brotli support. If that is not possible either, systems that use Brotli should not be reachable from untrusted networks or from within cloud environments (CERT-SE).
  • Limit the damage: Run Node.js services under a user without special privileges, and avoid keeping secrets in the process's environment variables where possible (Sysdig).

Detecting signs of an attack

The memory corruption itself leaves hardly any traces in application logs. Tanium and ELLIO list signals worth investigating:

  • repeated crashes or restarts of Node.js workers and other services that decompress Brotli – especially if requests with Content-Encoding: br appear in your WAF or proxy logs during the same period (Tanium)
  • hanging requests or workers with persistently high CPU load in Python, PHP, or Ruby services: according to ELLIO, their decoders do not crash on crafted data but produce no output and never return (ELLIO)
  • unusually large Brotli-encoded request bodies; the attack recorded by ELLIO was about 23 MB in size (ELLIO)
  • Brotli responses from unusual destinations in your outbound connection logs (Tanium)
  • follow-up activity, such as Node.js processes that start a shell, call download tools, or run programs from temporary directories, as well as changes to authorized_keys, cron, or systemd units (Tanium)

A single crash does not prove an attack. Imperva advises correlating crashes with the runtime version, application logs, and the origin of the data (Imperva). Requests from exposure checkers that only test whether a server decompresses Brotli are not an attack in themselves. ELLIO, however, considers them reconnaissance that can precede a wave of attacks. Forced crashes can also produce memory dumps (core dumps) containing session data and credentials of other users; ELLIO recommends restricting access to such dumps and limiting how long they are kept (ELLIO).

If an internet-facing service ran with a vulnerable decoder, check after the update whether credentials, tokens, and keys need to be rotated – the vulnerability can also disclose memory contents. If you have a concrete suspicion, a compromise assessment clarifies whether attackers left traces. If an attack is already visible, report the emergency directly to our team.

Not sure where Brotli runs in your environment? A vulnerability assessment examines your systems from the outside and, with authenticated scans, from the inside. It identifies installed packages and patch levels and prioritizes the findings. A secure code review with dependency analysis and an SBOM uncovers bundled and statically linked libraries in your own software.

Checklist: working through Broccoli2Shell

  • Every Node.js runtime is inventoried, including in containers, CI runners, and serverless functions, and checked with node --version (for distribution packages, also the version of the Brotli package)
  • Node.js runs 22.23.4, 24.22.1, 26.12.1, or later; Node.js 20, 23, and 25 have been replaced
  • Brotli and brotlicffi for Python are on 1.2.1 and 1.2.1.0, respectively, and the distribution's Brotli packages match the security notice
  • .NET is updated, and self-contained and NativeAOT applications have been rebuilt
  • Every affected process has been restarted, and container images have been rebuilt and verified
  • Firewalls with TLS inspection, appliances, and third-party products have been checked against the vendor advisories
  • Until the update, Brotli-encoded requests from untrusted clients are rejected
  • Logs have been checked for crashes and Brotli requests, and credentials on exposed systems have been assessed

Conclusion: patch, restart, know your dependencies

Broccoli2Shell shows how far a single flaw can reach in a library that often arrives only as a dependency: from Node.js and Python to .NET, firewalls, and browsers. A Node.js update alone is therefore not enough. What matters is finding every copy of the decoder, updating it, and restarting the processes – containers included. Since ENISA and CISA report that the vulnerability is already being exploited, internet-facing services belong at the top of the list. In the long run, patch management that also covers bundled libraries and relies on a well-maintained SBOM pays off.

Sources

All sources accessed on October 30, 2026.

Frequently asked questions

Is my application affected if it does not use Brotli compression itself?

Possibly, yes. Many frameworks and HTTP clients decompress Brotli data automatically: Express 5 does so for incoming request bodies, and fetch() in Node.js for fetched responses. In Python, requests, aiohttp, and HTTPX do the same as soon as the Brotli or brotlicffi package is installed. These packages are often pulled in unnoticed as dependencies. What matters is whether data from untrusted sources is decompressed anywhere with a vulnerable decoder. Using Brotli only for compression does not trigger the flaw.

Why does process.versions.brotli still show the old version after the update?

Node.js only applied the fix from the Brotli project and did not bump the version number of the bundled library. Patched versions therefore report the same Brotli version as vulnerable ones, for example 1.2.0 on Node.js 24. Check the Node.js version with node --version instead: 22.23.4, 24.22.1, 26.12.1, and later are fixed. If Node.js from a distribution package uses the system's Brotli library, the version of the system's Brotli package is what counts.

Is it enough to update Node.js?

In many environments, no. The vulnerable decoder can also be present in Python packages, in your Linux distribution's Brotli library, in .NET, in firewalls, and in products with an embedded copy of Brotli. In addition, an update only takes effect once the processes have been restarted and the container images rebuilt. Only a complete inventory shows where fixes are needed.

Are Node2Shell, Brotli2Shell, and Broccoli2Shell different vulnerabilities?

No. All of these names, as well as “HTTP2Shell,” refer to the same vulnerability, CVE-2026-111497 in the Brotli decoder. “Node2Shell” is the name the Imperva Red Team gave its analysis. The other names make clear that the vulnerability reaches far beyond Node.js.

Share article

Contact

Not sure whether your systems are affected?

We help you locate vulnerable copies of Brotli in your environment, prioritize the updates, and check for traces of a possible attack.

Get in touch+49 2932 465265-0

Author

Rootsektor Editorial Team

Team of Rootsektor IT-Security GmbH

Under this name, the team of Rootsektor IT-Security GmbH publishes articles on vulnerabilities, attack techniques, and defense. The company offers vendor-independent penetration testing, security services, and incident response and forensics, and is editorially responsible for the articles.

About Rootsektor

Transparency note: This article was created with the support of AI tools. Editorial responsibility for its content and statements lies with Rootsektor IT-Security GmbH.

Related services

Glossary terms

Blog

More articles

All articles
  • Vulnerabilities & Advisories

    php2shell: Critical PHP Vulnerabilities and What to Do Now

    · Approx. 12 min read

    Two critical flaws in the PHP core let attackers run code on web servers without authentication. Which versions are affected, how the vulnerabilities work, and what you need to do now.