Aikido

Node2Shell evolves to HTTP2Shell. Brotli flaw (CVE-2026-111497) blast radius affects many libraries & apps using HTTPs.

Buckle up.

Written by
Dania Durnas

TL;DR

⚠️ Developing: Brotli is used widely beyond Node.JS and Python. We have detected that CVE-2026-111497 affects other major languages and service applications, where patches are not yet available.

Check if you are using Brotli as a dependency within your libraries. Stay on guard for wider announcements and be ready to upgrade as soon as possible accross the board.

To start, Python. The Brotli flaw behind Node2Shell (CVE-2026-111497) also affects Python. Two PyPI packages, Brotli and brotlicffi, compile the same vulnerable Brotli decoder that Node.js bundles. An official advisory was posted on GitHub. Brotli has 82.8 million downloads per month.

You're affected if any Python environment you run has Brotli 1.2.0 or earlier, or brotlicffi 1.2.0.x, installed. Popular HTTP clients such as requests and httpx load these packages automatically when they're present. Some packages automatically install Brotli as a dependency such as Scrapy, while others require explicit mention of it. An attacker can reach the vulnerable decoder by sending a malicious Brotli response to a request your app makes, or by sending your app a request body compressed with Brotli. That means an app can be exposed without importing Brotli anywhere in its own code. It’s a popular transitive dependency, so check your systems.

To fix it, upgrade to the patched releases:

  • Brotli -> 1.2.1
  • brotlicffi -> 1.2.1.0

The release notes for both fixed versions don't mention the CVE. As of October 23, advisory databases don't map it to either PyPI package yet, so pip-audit, Dependabot, and Safety won't flag these versions.

Aikido detects the vulnerable versions and shows you which repositories and container images still include them.

Who is affected by CVE-2026-111497 in Python?

You’re affected if any of your Python environments have one of these packages installed:

PackageAffected versionsFixed version
Brotli (PyPI)1.2.0 and earlier1.2.1
brotlicffi (PyPI)1.2.0.x1.2.1.0

Your code doesn’t have to import either package. These HTTP clients advertise Accept-Encoding: br and decode Brotli responses automatically:

  • urllib3 (and therefore requests) when Brotli or brotlicffi is installed
  • httpx with the brotli extra
  • aiohttp when Brotli is installed
  • Scrapy, and anything built on the clients above

Attacker data can reach the decoder through two routes:

  • Outbound requests. Your app fetches a Brotli response from a server an attacker controls, such as through a webhook delivery, URL preview, crawler or “fetch this URL” feature.
  • Inbound requests. Your framework or middleware decodes a request body sent with Content-Encoding: br, which is the Python equivalent of the Express 5 case in Node.js.

How to fix CVE-2026-111497 in Python

The fix is a package upgrade, and it takes four steps:

  1. Upgrade whichever package you have installed with pip install -U "Brotli>=1.2.1" or pip install -U "brotlicffi>=1.2.1.0". If you use a lockfile with Poetry, uv, or pip-tools, update the constraint and regenerate the lockfile.
  2. Rebuild your container images and any wheels that bundle either package. An image built on a vulnerable version stays vulnerable until you rebuild it.
  3. Check every environment you run, including laptops, CI runners, servers and containers. Many projects pull in Brotli through an HTTP client extra, so look at your full resolved dependency tree.
  4. Rely on a manual check for now. pip-audit, Dependabot and Safety won't report this until the advisory databases map the CVE to the PyPI packages.

If your Python Brotli bindings came from a Linux distribution package instead of PyPI, the fix comes through your distribution, so check its security advisory as well.

How Aikido helps with CVE-2026-111497

Aikido flags vulnerable versions of Brotli and brotlicffi in your repositories, container images, and dependencies, including when they arrive as transitive dependencies. Your dashboard shows which services still run a vulnerable version, so you can upgrade the ones that call outside servers or accept compressed request bodies first. 

Once you've upgraded, Aikido checks if the finding is gone.

Python2Shell technical details

What is Python2Shell (CVE-2026-111497)?

Python2Shell refers to CVE-2026-111497, the Brotli decoder flaw known as Node2Shell, as it affects Python packages on PyPI. The CVE record pairs CWE-252 (unchecked return value) with CWE-787 (out-of-bounds write).

The flaw sits in DecodeBlockTypeAndLength(), which handles block switches, the points where a Brotli stream changes which Huffman tree it uses. In vulnerable versions the function returns a plain boolean, and BROTLI_FALSE can mean either "this stream is malformed" or "I need more input." Callers can't tell the two apart, and on the fast path the decoder discards the return value entirely.

A crafted stream can declare a single block type and then exhaust that block's length, which forces a switch that can't succeed. The decoder then either reports that it needs more input for a stream that's complete, or keeps decoding with the block state it already had. That second path leads to the out-of-bounds write.

The upstream fix, google/brotli commit 0ed4268, makes the function return an error code and adds a new error, BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH (-17). Decoding now stops on a format error on both the safe and fast paths. OSM diffed the Brotli 1.2.0 and 1.2.1 source distributions and found that 1.2.1 differs only in the version bump and the decoder changes from that commit.

How serious is CVE-2026-111497 for Python, and is it being exploited?

The CVE record gives the flaw a CVSS 4.0 score of 9.2, and Node.js rates it high severity. OSM built Brotli 1.2.0 and 1.2.1 with AddressSanitizer and ran a crafted stream through both. Version 1.2.0 consumed all of the roughly 23 MB stream and kept reporting that it needed more input, whether the stream arrived in one piece or in chunks as small as one byte. Version 1.2.1 rejected the stream with error -17 every time.

OSM didn't pursue memory corruption or code execution in the Python extension. The decoder code is the same code that researchers exploited against an unmodified Node.js 24.22.0 build, as Imperva and others reported. For Node.js, The Hacker News reported no exploitation in the wild as of October 22.

Treat it as urgent anyway. The bug is a memory-safety flaw in a component that handles untrusted network input, and the fix is a routine version bump. Services that call outside servers or accept compressed request bodies should go first.

How to check if your app is exposed

  1. Check installed versions with pip show Brotli brotlicffi in each environment, and with docker run --rm <image> pip show Brotli brotlicffi for each container image.
  2. Find what pulls the packages in. Run pipdeptree -r -p Brotli to see which dependencies require it, and search your lockfiles with grep -i brotli poetry.lock uv.lock requirements*.txt.
  3. List the outbound HTTP calls that go to servers you don't control, and any endpoints that decode Content-Encoding: br request bodies.
  4. Upgrade the services that match step 3 first, then the rest.

If you're reproducing the bug from Python, brotli.decompress() raises a generic brotli.error: decoder failed for any error, so you can't see which error code fired. A Decompressor() fed the crafted stream incrementally will never finish on 1.2.0.

What to do if you can't upgrade yet

These workarounds reduce exposure while you prepare the upgrade:

  • Uninstall Brotli and brotlicffi. The HTTP clients above fall back to gzip and deflate without them. If a dependency installs Brotli through an extra such as httpx[brotli], remove the extra as well, or the next install brings the package back.
  • Strip br from Accept-Encoding on outbound requests and reject Content-Encoding: br on inbound requests at your reverse proxy, load balancer or application middleware.

Uninstalling removes the vulnerable decoder from the environment, so it covers both directions. Header changes give weaker protection for outbound traffic, because a malicious server can send a Brotli response regardless of what your request advertises, and urllib3 decodes based on the response's Content-Encoding header.

Python2Shell timeline

  • February 2026: The fix is first committed to the Brotli source code.
  • October 21, 2026: Node.js releases patched versions for Node2Shell, and Brotli publishes fixed upstream releases, including 1.2.1.
  • October 22, 2026: Brotli 1.2.1 appears on PyPI.
  • October 23, 2026: brotlicffi 1.2.1.0 appears on PyPI, and OpenSourceMalware.com publishes its research on the Python packages.

FAQ

What is Python2Shell?

Python2Shell is CVE-2026-111497, the Brotli decoder flaw known as Node2Shell, as it affects the Brotli and brotlicffi packages on PyPI.

Which versions fix CVE-2026-111497 in Python?

Brotli 1.2.1 and brotlicffi 1.2.1.0, along with any newer releases.

Do I need to import Brotli in my code to be affected?

An installed package is enough. urllib3, requests, httpx and aiohttp use Brotli or brotlicffi automatically when either is present and decode Brotli responses from any server your app calls.

Will pip-audit or Dependabot flag this?

Not yet. As of October 23, the CVE record, OSV and the GitHub Advisory Database don't list either PyPI package. OSM is submitting PYSEC entries and a PyPI package mapping for the GitHub advisory so that tooling picks this up.

Is there a workaround?

Uninstalling Brotli and brotlicffi removes the vulnerable decoder, and HTTP clients fall back to gzip and deflate. Rejecting Brotli-encoded requests at the edge reduces inbound exposure, but it doesn't protect against Brotli responses your app fetches.

‍

Share:

https://www.aikido.dev/blog/python-packages-vulnerable-node2shell-brotli-cve-2026-111497

Check for vulnerabilities

Start now
4.7/5
Tired of false positives?

Try Aikido like 100k others.
Start Now
Get a personalized walkthrough

Trusted by 100k+ teams

Book Now
Scan your app for IDORs and real attack paths

Trusted by 100k+ teams

Start Scanning
See how AI pentests your app

Trusted by 100k+ teams

Start Testing

Get secure today,
quickly and for free.

Secure your code, cloud, and runtime in one central system.
Connect a repo to discover what the reasoning agents find in your codebase.

No credit card required | Scan results in 32 seconds.
Trusted by 150k+ orgs