How to Patch Node2Shell and HTTP2Shell on VMs, Containers and Kubernetes
Find and patch vulnerable Brotli decoders across Node.js, Bun, Python, container images and Kubernetes, then verify each running workload.

Node2Shell (CVE-2026-111497) started as a Node.js bug and turned into HTTP2Shell: an out-of-bounds write in Google's Brotli decoder that ships inside Node.js, Bun, Python packages, .NET, Envoy, Istio and many Linux distros. Public proof-of-concept code exists, so treat it as urgent. This guide shows how to find every copy of the vulnerable decoder and patch it on VMs, in container images and across Kubernetes.
If you missed the background, read our breakdown of the October 2026 2Shell attacks first.
Before you start: what "patched" means
These are the fixed versions as of 30 October 2026:
Node.js: 22.23.4, 24.22.1 or 26.12.1. Node 20, 23, 25 and older are end-of-life and get no fix.
Bun: 1.4.4 or later.
Python: Brotli 1.2.1 and brotlicffi 1.2.1.0.
Google Brotli (libbrotli): 1.2.1, 1.1.1 or 1.0.10.
.NET: 8.0.33, 9.0.22 or 10.0.14. .NET 7 gets no fix.
Envoy: 1.40.0, 1.39.3, 1.38.6 or 1.37.8.
Istio: 1.31.2, 1.30.6 or 1.29.9.
Java brotli4j: 1.24.0.
Who is exposed first: services that decompress untrusted Brotli data. That includes Express 5 and body-parser 2, which decode Content-Encoding: br request bodies by default, and any service that uses fetch(), requests, aiohttp or httpx to call URLs it doesn't control.
Part 1: Patch on a VM
Find every runtime on the machine
Official Node.js binaries bundle their own Brotli, so updating the OS library does not fix them. Start by finding every copy.
Check the active Node.js version:
node --versionList every node binary on the PATH:
which -a nodeList versions installed with nvm:
ls ~/.nvm/versions/nodeUpgrade Node.js
With nvm, install a fixed version:
nvm install 24.22.1Make it the default:
nvm alias default 24.22.1With NodeSource or distro packages on Debian and Ubuntu:
sudo apt update && sudo apt install --only-upgrade nodejsOn RHEL, AlmaLinux and Rocky Linux:
sudo dnf upgrade nodejsUpgrade Bun
bun upgradeThen rebuild any executables made with bun build --compile, because they embed the old decoder.
Upgrade Python Brotli
Run this in every virtualenv and in the system Python that runs services:
pip install --upgrade "brotli>=1.2.1" "brotlicffi>=1.2.1.0"Check the installed versions:
pip show brotli brotlicffiUpdate the system Brotli library
Distro Node.js packages, curl and other tools use the system library.
Debian and Ubuntu:
sudo apt update && sudo apt install --only-upgrade libbrotli1Alpine:
apk update && apk upgrade brotli-libsAmazon Linux 2023, RHEL and Fedora:
sudo dnf upgrade brotliFixed builds include Debian 12 (1.0.9-2+deb12u1), Debian 13 (1.1.0-2+deb13u1), Alpine 3.23 and 3.24 (1.2.1-r0) and Amazon Linux 2023 (1.1.0-1.amzn2023.0.2). Check your distro's security tracker for Ubuntu, RHEL and SUSE, where fixes were still rolling out.
Restart and verify
Restart every service that runs Node.js, Bun or Python:
sudo systemctl restart <your-service>On Debian and Ubuntu, list services still using old libraries:
sudo needrestart -r lPart 2: Patch the container image
Node.js images
Bump the base image in your Dockerfile to a fixed tag:
Node 22: node:22.23.4 (also -slim and -alpine)
Node 24: node:24.22.1
Node 26: node:26.12.1
Your Dockerfile's first line becomes:
FROM node:24.22.1-alpineImages on node:20 or older have no fixed tag. Move to Node 22 or 24.
Python, Bun and .NET images
Python: pin brotli>=1.2.1 and brotlicffi>=1.2.1.0 in requirements.txt or your lockfile.
Bun: use oven/bun:1.4.4 or later.
.NET: rebuild on the 8.0.33, 9.0.22 or 10.0.14 runtime images. Self-contained apps must be rebuilt, because they carry their own runtime.
Rebuild without cache
Floating tags and cached layers keep the old decoder. Rebuild from scratch:
docker build --pull --no-cache -t registry.example.com/api:2026-10-30 .Verify the image
Check the Node.js version inside the image:
docker run --rm registry.example.com/api:2026-10-30 node --versionCheck Python Brotli inside the image:
docker run --rm registry.example.com/api:2026-10-30 pip show brotliScan the image:
trivy image registry.example.com/api:2026-10-30Push the image with a new, unique tag:
docker push registry.example.com/api:2026-10-30Part 3: From Docker to Kubernetes — roll it out
Step 1: Find every workload image. Look for node, bun, python and dotnet bases, and your own apps built on them.
kubectl get pods -A -o jsonpath='{..image}' | tr ' ' '\n' | sort -uStep 2: Update the image. Commit the new tag in GitOps or Helm, or for a quick manual change:
kubectl set image deployment/api api=registry.example.com/api:2026-10-30 -n prodStep 3: Watch the rollout.
kubectl rollout status deployment/api -n prodStep 4: Verify inside a running pod.
kubectl exec -n prod deploy/api -- node --versionStep 5: Check your service mesh. Envoy and Istio are only exposed when a Brotli decompressor filter is configured. Find any:
kubectl get envoyfilters -A -o yaml | grep -i brotliCheck your Istio version:
istioctl versionIf you use the Brotli decompressor, upgrade Istio to 1.31.2 or 1.30.6, or Envoy to a fixed release, then restart workloads so sidecars pick up the new proxy:
kubectl rollout restart deployment -n prodStep 6: Rotate secrets. If a service that decompresses untrusted input was exposed before you patched, rotate its API keys, database passwords and tokens.
Can't patch today?
Express 5 / body-parser 2: turn off request decompression where you don't need it, with app.use(express.json({ inflate: false })); and the same option on urlencoded, text and raw parsers.
At the edge: have your proxy or WAF reject requests with Content-Encoding: br if your apps don't need them.
Python services that fetch untrusted URLs: uninstall the Brotli packages. Clients fall back to gzip and deflate.
Outbound calls: limit which external hosts your services can call.
Quick checklist
Every VM runs Node.js 22.23.4, 24.22.1 or 26.12.1, and nothing older is left on the PATH or in nvm
Bun is on 1.4.4 or later, and compiled Bun binaries were rebuilt
Python Brotli and brotlicffi are upgraded in every environment and image
The system Brotli library is patched, and services were restarted
Every image was rebuilt with no cache and pushed with a unique tag
Every pod runs the new image, and Envoy or Istio is patched if it decompresses Brotli
Secrets were rotated on anything exposed before the patch
How Turf Dev can help
Node2Shell is hard because the vulnerable code hides in runtimes, libraries, base images and proxies. Turf Dev runs Kubernetes and cloud security audits that inventory every image and runtime, find the vulnerable copies, and rescan after patching to prove they are gone. If you want help with your Node2Shell rollout, reach out at turfdev.in.
1 of 5 sections shown




Discussion
Have a question or something to add? Share it below.
No comments yet. Be the first to join the discussion.