In late October 2026, security researchers disclosed HTTP2Shell (officially tracked as CVE-2026-111497), an unauthenticated heap buffer overflow vulnerability in Google's open-source Brotli compression and decompression library. Carrying a critical CVSS v4.0 score of 9.2, this flaw enables remote attackers to trigger out-of-bounds memory writes and achieve remote code execution (RCE) on servers handling compressed web traffic. Because Brotli is bundled by default across modern language runtimes and reverse proxies, the breaking HTTP2Shell news alert forced emergency patch cycles across the cloud-native ecosystem.
This operational guide breaks down the architectural root cause of HTTP2Shell, provides an immediate multi-runtime vulnerability matrix, details copyable detection scripts, and demonstrates edge ingress mitigations for Kubernetes clusters.
What Is HTTP2Shell and How Does the Brotli Buffer Overflow Work?
HTTP2Shell (CVE-2026-111497) is an out-of-bounds heap write vulnerability in Google's Brotli C decoder library affecting versions 1.0.3 through 1.2.0. It triggers when a streaming decoder encounters a malformed block switch header, mistakenly treating an invalid state as an incomplete frame and overrunning its internal 8-byte buffer with incoming network data.
To understand the mechanics of http2shell, we must examine how streaming decompression functions in high-throughput network stacks. When a client issues an HTTP request containing Content-Encoding: br or when a microservice decodes an upstream compressed response, the runtime passes stream chunks into Brotli's C decoder function, BrotliDecoderDecompressStream().
In vulnerable library versions, the decoder maintains an internal fixed-size staging buffer of 8 bytes for multibyte block switch commands. When parsing a maliciously constructed bitstream containing an invalid block switch marker, the state machine fails to transition into an error state (BROTLI_DECODER_RESULT_ERROR). Instead, it returns BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT. As subsequent data chunks arrive over the socket, the decoder continues appending bytes past the bounds of the 8-byte buffer directly into adjacent heap memory.
Content-Encoding: br and malformed block switch commands.NEEDS_MORE_INPUT instead of returning a parse error.While the vulnerability received the moniker HTTP2Shell (and earlier Node2Shell during initial triage), the underlying bug resides exclusively inside the Brotli decompression engine. However, modern HTTP/2 connections exacerbate the exploitability: HTTP/2 multiplexing allows attackers to pipeline malformed compression frames rapidly without tearing down underlying TCP connections, evading legacy stateful inspection.
The 970+ Incident Handbook & K8s Runbooks are exclusive to subscribers — unlock for FREE
Get battle-tested production runbooks, AWS architecture blueprints, and zero-downtime CI/CD post-mortems sent directly to your inbox. 100% free, no spam.
Which Runtimes and Cloud Native Workloads Are Vulnerable?
HTTP2Shell affects all language runtimes, reverse proxies, and microservices statically or dynamically compiled against libbrotli versions 1.0.3 through 1.2.0. Node.js, Bun, Python packages with native C extensions, Microsoft .NET, and specific builds of Envoy proxy require immediate runtime upgrades to eliminate arbitrary memory overwrite risks.
As documented during our triage of the broader Black October vulnerabilities, modern software supply chains tightly couple compiled native libraries into higher-level scripting runtimes. The following table highlights the exact impact matrix across standard enterprise architectures:
| Ecosystem / Runtime | Vulnerable Versions | Patched Release | Attack Vector | Verification Command |
|---|---|---|---|---|
| Node.js (LTS & Current) | 26.x < 26.12.1 24.x < 24.22.1 22.x < 22.23.4 |
26.12.124.22.122.23.4 |
Inbound request body parsing via zlib.createBrotliDecompress() |
node -p "process.versions.brotli" |
| Python (pip / wheel) | brotli < 1.2.1brotlicffi < 1.2.1.0 |
brotli >= 1.2.1brotlicffi >= 1.2.1.0 |
FastAPI/Flask request decompression, aiohttp, requests |
python3 -c "import brotli; print(brotli.__version__)" |
| Bun JavaScript Runtime | Bun < 1.4.4 | 1.4.4+ |
Automatic body stream decompression in HTTP server handlers | bun --version |
| Microsoft .NET Runtime | .NET 8.0 < 8.0.11 .NET 9.0 < 9.0.1 |
8.0.119.0.1 |
System.IO.Compression.BrotliStream ingestion |
dotnet --info |
| Upstream C / C++ libbrotli | 1.0.3 through 1.2.0 | 1.0.10 / 1.1.1 / 1.2.1 |
Direct memory corruption in compiled network utilities | ldconfig -p | grep brotli |
Step-by-Step Triage: Detecting HTTP2Shell Across Microservices
Platform teams can detect HTTP2Shell vulnerabilities across live clusters using container Software Bill of Materials (SBOM) scanners and runtime introspection. Running automated scanners like Trivy against registry repositories and executing targeted namespace audits reveals vulnerable libbrotli binaries in base images before attackers initiate exploitation.
When triaging a production cluster under active threat advisories, follow this structured investigation sequence to audit running workloads:
1. Audit Running Node.js and Python Pods with Kubectl
To inspect your running Kubernetes workloads without taking them offline, execute one-line diagnostic sweeps across target namespaces:
# Check embedded Brotli version in all running Node.js production pods
kubectl get pods -n production -l app.kubernetes.io/name=api-gateway \
-o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{"\n"}{end}{end}'
# Exec runtime version query on a candidate container
kubectl exec -n production deploy/api-gateway -c app -- node -e '
const ver = process.versions.brotli;
console.log(`[AUDIT] Node ${process.version} | libbrotli: ${ver}`);
if (ver && ver < "1.2.1") {
console.error("[CRITICAL] Vulnerable to HTTP2Shell (CVE-2026-111497)");
process.exit(1);
}
'
A vulnerable workload will return the following output indicating an unpatched C library:
[AUDIT] Node v24.20.0 | libbrotli: 1.1.0
[CRITICAL] Vulnerable to HTTP2Shell (CVE-2026-111497)
command terminated with exit code 1
2. Automated Container Registry Scanning with Trivy
Before promoting images through your CI/CD pipelines, integrate container security gates as described in our guide to CI/CD Trivy vulnerability blocking. Scan base images for the specific CVE identifier:
# Run high-priority vulnerability scan for CVE-2026-111497
trivy image \
--severity CRITICAL \
--vuln-type os,library \
--pkg-types os,library \
--select-policy "cve == 'CVE-2026-111497'" \
production-registry.internal/payments/checkout-service:v2.14.0
The scanner flags vulnerable native dependencies immediately:
2026-10-27T12:15:00Z INFO Scanning image production-registry.internal/payments/checkout-service:v2.14.0
checkout-service:v2.14.0 (debian 12.6)
Total: 1 (CRITICAL: 1)
Vulnerability: CVE-2026-111497
Package: libbrotli1 (installed: 1.0.9-2+b6, fixed: 1.0.9-2+deb12u1)
Severity: CRITICAL
Title: brotli: Heap buffer overflow in BrotliDecoderDecompressStream
Status: fixed
For large enterprise clusters with hundreds of container repositories, enforce continuous baseline scanning following standard Docker image security and ECR governance policies.
Immediate Production Mitigations: WAF, Envoy, and NGINX Ingress Filters
When immediate container patching across hundreds of microservices is impossible, platform engineers must implement edge mitigations that drop or strip inbound Brotli compression. Applying WAF inspection rules or ingress gateway filters stops malicious Content-Encoding: br payloads before they reach application memory spaces.
Because the exploit relies on the server decompressing an untrusted inbound request body, blocking or stripping decompression at the ingress controller provides an instantaneous zero-downtime defense.
Option A: Strip Content-Encoding in NGINX Ingress Controller
If your ingress routing is managed by ingress-nginx, inject a configuration snippet to reject or sanitize incoming Brotli request payloads while continuing to allow standard gzip and identity streams:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-gateway-ingress
namespace: production
annotations:
kubernetes.io/ingress.class: "nginx"
# Block requests attempting inbound Brotli decompression
nginx.ingress.kubernetes.io/server-snippet: |
if ($http_content_encoding ~* "br") {
return 415 "Unsupported Media Type: Inbound Brotli compression disabled for CVE-2026-111497 mitigation\n";
}
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-gateway
port:
number: 8080
Option B: Istio / Envoy EnvoyFilter for Service Mesh Zero-Trust
If microservices communicate over an Istio service mesh, deploy an EnvoyFilter to intercept and drop inbound requests advertising Brotli content encoding before the upstream proxy passes frames to the pod:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: block-http2shell-brotli
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inlineCode: |
function envoy_on_request(handle)
local encoding = handle:headers():get("content-encoding")
if encoding and string.find(string.lower(encoding), "br") then
handle:respond(
{[":status"] = "415", ["content-type"] = "text/plain"},
"Blocked by Mesh Security: Inbound Brotli disallowed (CVE-2026-111497)\n"
)
end
end
Permanent Remediation: Container Rebuilds and CI/CD Security Gates
Permanent resolution of HTTP2Shell requires upgrading underlying base images and native language packages across all container Dockerfiles. Updating Node.js to version 26.12.1/24.22.1/22.23.4, upgrading Python wheels to brotli 1.2.1, and rebuilding OCI containers completely neutralizes the heap corruption path.
Follow this checklist to execute permanent container remediation across your application fleet:
1. Update Node.js Dockerfiles
Switch to official patched base image tags. If building on Alpine Linux or Debian Bookworm, verify the installed OS package versions during the multi-stage build:
# Patched Node.js container build
FROM node:24.22.1-bookworm-slim AS build
WORKDIR /app
# Ensure OS security patches are fetched
RUN apt-get update && \
apt-get install -y --no-install-recommends libbrotli1 && \
rm -rf /var/lib/apt/lists/*
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
# Run as non-privileged service user
USER node
EXPOSE 3000
CMD ["node", "dist/index.js"]
2. Update Python Requirements and Lockfiles
For Python microservices, enforce explicit minimum versions in your pyproject.toml or requirements.txt file:
# Explicitly pin patched Brotli bindings to fix CVE-2026-111497
brotli>=1.2.1; platform_python_implementation == 'CPython'
brotlicffi>=1.2.1.0; platform_python_implementation == 'PyPy'
urllib3>=2.3.0
Re-generate your lockfile using poetry or pip-compile, commit the updated hashes to git, and verify the build through a standardized DevOps CI/CD pipeline setup.
Production Incident Postmortem & Defense-in-Depth Lessons
The disclosure of HTTP2Shell highlights the severe blast radius of legacy native C dependencies embedded inside managed runtime stacks. Platform teams must minimize container attack surfaces using distroless images, disable unnecessary decompression decoders by default, and enforce strict egress firewall policies.
Organizations that weathered the disclosure without emergency fire drills shared four fundamental architectural characteristics:
- Distroless and Minimal Base Images: Workloads running on Chainguard or Google Distroless images contained only strictly necessary shared libraries, drastically simplifying SBOM audit queries and eliminating unneeded utilities.
- Request Decompression Guardrails: Modern API architectures rarely require inbound HTTP body compression from untrusted clients. By restricting Brotli compression strictly to outbound response streams, their edge gateways were immune to inbound exploit vectors.
- Non-Root and Read-Only Filesystems: Even if heap memory corruption occurs, running containers as unprivileged users (
runAsNonRoot: true) with a read-only root filesystem (readOnlyRootFilesystem: true) prevents attackers from dropping shell payloads or installing persistence tools. - Strict Network Policies: Enforcing default-deny egress policies via Kubernetes
NetworkPolicyprevents reverse shells from dialing out to command-and-control (C2) listeners even in worst-case remote code execution conditions.
Frequently Asked Questions
What is HTTP2Shell (CVE-2026-111497)?
HTTP2Shell is a critical out-of-bounds write vulnerability (CVSS 9.2) in Google's Brotli C decompression library (versions 1.0.3 to 1.2.0). When an application decompresses untrusted Content-Encoding: br payloads, an invalid block switch misinterprets errors as requests for more data, writing past an 8-byte internal buffer and enabling remote code execution.
Does HTTP2Shell exploit the HTTP/2 protocol directly?
No. Despite the nickname 'HTTP2Shell', the vulnerability is not in the HTTP/2 protocol specification. It derives from HTTP servers, microservices, and reverse proxies that automatically negotiate HTTP/2 with Brotli (br) compression on inbound request or response bodies.
Which runtimes and libraries are vulnerable to HTTP2Shell?
Vulnerable environments include Node.js (26.x before 26.12.1, 24.x before 24.22.1, 22.x before 22.23.4), Bun (< 1.4.4), Python packages using native Brotli C bindings (brotli < 1.2.1, brotlicffi < 1.2.1.0), Microsoft .NET runtimes, and reverse proxies or service meshes compiling libbrotli.
How can platform teams mitigate HTTP2Shell before container images are patched?
Platform engineers can immediately block or strip the Content-Encoding: br and Accept-Encoding: br headers at edge ingress proxies (such as Cloudflare, AWS CloudFront, Envoy, or NGINX) or configure API gateway request body filters to reject compressed request payloads.