Node2Shell, Python2Shell, HTTP2Shell und Broccoli2Shell sind Namen für dieselbe Lücke. Sie ist nicht zu verwechseln mit PHP2Shell (CVE-2026-109618/-109619), einer davon unabhängigen PHP-Lücke, die bereits aktiv ausgenutzt wird.
Worum es geht
Der Brotli-Decoder von Google (c/dec/decode.c, Versionen 1.0.3 bis 1.2.0) schreibt beim Entpacken manipulierter Daten über das Ende seines Puffers hinaus. Gefixt ist das in Brotli 1.0.10, 1.1.1 und 1.2.1, veröffentlicht am 21.10.2026. Die Lücke hat CVSS 4.0 9.2.
Warum das gefährlich ist:
- Ein Angreifer braucht keinen Login. Ein Request mit
Content-Encoding: brreicht. Mögliche Folgen sind Absturz, Speicherleck oder Remote Code Execution. - Ausgehende Requests sind genauso betroffen. Holt der eigene Dienst eine Antwort von einem bösartigen Server und entpackt sie als Brotli, schlägt die Lücke dort zu. Eine Proxy-Regel für eingehenden Traffic hilft dagegen nicht.
- Brotli kommt oft nur als transitive Abhängigkeit ins Projekt, in HTTP-Clients, Sidecars und Base-Images.
- Seit dem 22.10. gibt es öffentlichen Exploit-Code. Seit dem 24.10. liegt laut Mallory auch ein öffentlicher Exploit gegen das offizielle, unveränderte Image Node 24.22.0 auf x86_64 vor. Er greift eine Express-5-/body-parser-2.x-Route an, die große Request-Bodies annimmt, und trifft in einem von sieben bis zehn Versuchen. Jeder Fehlversuch bringt den Worker zum Absturz. Startet ein Process Manager ihn neu, versucht es der Exploit einfach wieder. Unabhängig bestätigt hat das bisher niemand: Aikido und Brandefense kennen nur öffentlichen Code, der Abstürze auslöst oder auf einem absichtlich geschwächten Build läuft.
- Mit eigenen, nicht veröffentlichten Exploits haben Forscher Code Execution auf dem offiziellen Image Node 24.22.0 gezeigt: Imperva auf arm64 nach mehreren Versuchen, OtterSec laut Robert Chen auf x86_64 mit ASLR in 50 von 50 Versuchen (geschrieben von einem KI-Agenten in fünf Stunden).
- Aktive Angriffe sind laut Mallory und NCSC-NL bis 25.10. nicht bekannt. Der EPSS-Wert liegt bei 0,7 %. CISA führt die Lücke am 26.10. noch nicht im KEV-Katalog (Version 2026.10.23).
- [update] ELLIO meldet den ersten echten Ausnutzungsversuch. Am 26.10. um 15:08 UTC kam in ELLIOs Deception-Netz ein einzelner Brotli-Request mit 23.069.983 Bytes von 94.154.43.7 an, gebaut für Node 24.22.0 auf x86_64. Ob der Angreifer damit irgendwo Erfolg hatte, ist nicht bekannt. Davor hat ein Scanner mit dem User-Agent
node2shell-check/1.0aus AS44620 (Türkei) mit 20br-Bodies geprüft, welche Hosts Brotli überhaupt entpacken. Im Labor bekam ELLIO mit offiziellen Binaries auf allen vier Zielen eine Shell:node:httpmitnode:zlib, das Imagenode:24.22.0-slim, Express 5.3.0 mitexpress.json()und Koa 3 mit@koa/bodyparser6. Bestätigt hat den Angriff bisher nur ELLIO selbst. - [update] Der EPSS-Wert ist am 26.10. von 0,7 % auf 36,0 % gesprungen (Perzentil 98,5). Im KEV-Katalog (Version 2026.10.26) fehlt die Lücke weiterhin.
- [update 2] ELLIO hat Details nachgereicht: Die Exploit-Kette des Angreifers traf im Labor in 50 Versuchen gegen ein verwundbares Node 24.22.0 kein einziges Mal, ELLIOs eigene Kette bekam auf demselben Ziel eine Shell. Die Quell-IP 94.154.43.7 kennt ELLIO seit dem 15.12.2025, sie war an 47 der letzten 90 Tage aktiv. Eine erfolgreiche Kompromittierung meldet ELLIO nicht. Tenable hat den Vorfall nicht unabhängig bestätigt.
- [update 2] Der EPSS-Wert ist am 27.10. weiter auf 55,5 % gestiegen (Perzentil 99,0). Im KEV-Katalog (Version 2026.10.26) fehlt die Lücke weiterhin.
- [update 3] CISA hat die Lücke am 27.10. in den KEV-Katalog aufgenommen (Version 2026.10.27, Frist für US-Bundesbehörden 10.11.). Damit gilt sie offiziell als aktiv ausgenutzt. Details zu den Angriffen nennt CISA nicht.
- [update 3] Der EPSS-Wert liegt am 28.10. bei 88,0 % (Perzentil 99,8).
- [update 3] Previdian meldet laut SecurityWeek einen Ausnutzungsversuch am 27.10. von einer US-IP. Ob er erfolgreich war, sagt Previdian nicht. Die IP aus ELLIOs Fund hat laut ELLIO vorher schon PHP2Shell ausgenutzt und VPNs von Palo Alto und Fortinet abgetastet. ELLIO sieht darin einen Akteur, der auf Massenausnutzung aus ist. Eine erfolgreiche Kompromittierung hat bis 28.10. niemand gemeldet.
- [update 3] Auch Appliances sind betroffen: Broadcom meldet am 27.10. den SDDC Manager in VMware Cloud Foundation und vSphere Foundation (9.1.1: CVSS 9.8, 9.0.x/9.1.0/5.2.x: CVSS 7.5), weil er Node.js nutzt. Patches fehlen noch, Workarounds stehen in zwei KB-Artikeln. Palo Alto verteilt Hotfixes für PAN-OS.
- [update 4] Der EPSS-Wert liegt seit dem 29.10. bei 82,6 % (Perzentil 99,7), knapp unter dem Höchstwert vom 28.10. Der KEV-Eintrag ist unverändert (Version 2026.10.30, Frist 10.11.).
- [update 4] Neue Berichte über Angriffe oder eine erfolgreiche Kompromittierung habe ich seit dem 28.10. nicht gefunden. ELLIOs Blog hat seit dem 26.10. keinen neuen Eintrag.
- [update 4] Broadcom hat das Advisory am 30.10. als VMSA-2026-0008.1 überarbeitet. Patches für den SDDC Manager stehen weiter aus. Bis dahin gelten die Workarounds aus KB 460732 (9.1.1.x: nginx-Regel gegen Brotli-Bodies) und KB 460734 (5.2.x, 9.0.x, 9.1.0:
NODE_OPTIONSschaltet den Brotli-Decoder im UI-Dienst ab). Laut KB 460791 sind die übrigen Komponenten von VCF und VVF sowie Cloud Director, HCX, Remote Console, PowerCLI, Workstation und Fusion nicht kritisch betroffen. - Assetnote hat mit dem node2shell-scanner einen kostenlosen Scanner veröffentlicht. Er findet verwundbare HTTP-Endpunkte im Netz, ohne sie auszunutzen. Laut Shodan senden rund 1,41 Mio. Dienste
X-Powered-By: Expressund 878.000X-Powered-By: Next.js, dazu kommen rund 482.000 Envoy-/Istio-Gateways. - pip-audit, Dependabot und Safety haben die betroffenen Python-Versionen anfangs nicht gemeldet. Inzwischen führt GitHubs Advisory PYSEC-2026-4322 und PYSEC-2026-4323. Bis die Scanner nachweislich anschlagen, trotzdem manuell prüfen (siehe Python).
Betroffen ist nur nativer C-Code, also die Google-Bibliothek selbst und alles, was sie einbindet. Ein reiner Java-Decoder wie org.brotli:dec hat keinen Speicher-Overflow, weil die JVM jeden Array-Zugriff prüft. Das ist meine Einschätzung. Eine offizielle Aussage zu Java habe ich nicht gefunden.
Spring Boot
Für alle drei Server gilt dieselbe Frage: Liegt com.aayushatharva.brotli4j auf dem Classpath? brotli4j bringt die native Google-Bibliothek per JNI mit. Ohne brotli4j gibt es im JVM-Prozess keinen verwundbaren Decoder.
# Maven
mvn dependency:tree -Dincludes=com.aayushatharva.brotli4j
mvn dependency:tree -Dincludes=org.brotli
# Fertiges Fat-JAR
unzip -l target/*.jar | grep -i brotli
Gefixt ist das in brotli4j v1.24.0 vom 24.10.2026. Dieses Release hebt das mitgelieferte Brotli auf 1.2.1 und nennt CVE-2026-111497 im Security Advisory. Die Version per dependencyManagement erzwingen, weil Netty und Jetty ältere Versionen mitziehen. Die nativen Artefakte (native-linux-x86_64, native-linux-aarch64 usw.) müssen dieselbe Version haben, sonst lädt die alte native Bibliothek weiter.
[update 4] Red Hat führt das Artefakt native-linux-x86_64 (nach meiner Einschätzung die native Bibliothek von brotli4j) in Quarkus, Camel for Quarkus, Debezium 3 und Apicurio Registry 3 als betroffen, in Keycloak als nicht betroffen. Wer native Builds dieser Produkte nutzt, prüft sie wie eigene Spring-Projekte.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.aayushatharva.brotli4j</groupId>
<artifactId>brotli4j</artifactId>
<version>1.24.0</version>
</dependency>
<dependency>
<groupId>com.aayushatharva.brotli4j</groupId>
<artifactId>native-linux-x86_64</artifactId>
<version>1.24.0</version>
</dependency>
</dependencies>
</dependencyManagement>
Tomcat (spring-boot-starter-web, Standard)
Tomcat entpackt keine Request-Bodies und kann kein Brotli. server.compression komprimiert nur Antworten mit gzip. Der Server selbst ist nach meiner Einschätzung nicht betroffen.
Prüfen muss man trotzdem:
- ob brotli4j über eine andere Abhängigkeit reinkommt, etwa einen eigenen Decompression-Filter oder Netty als HTTP-Client (siehe nächster Abschnitt)
- welche HTTP-Clients ausgehend Brotli entpacken. Der JDK-
HttpClientkann kein Brotli. OkHttp (okhttp-brotli) und Apache HttpClient 5 nutzen den reinen Java-Decoderorg.brotli:decund sind damit unkritisch.
Netty (spring-boot-starter-webflux, Reactor Netty)
Hier ist das Risiko am größten. Netty lädt brotli4j als optionale Abhängigkeit. Liegt es auf dem Classpath, liefert Brotli.isAvailable() true, und HttpContentDecompressor entpackt br automatisch mit dem nativen Code.
- Server: Reactor Netty entpackt Request-Bodies standardmäßig nicht. Betroffen ist man, wenn man selbst einen
HttpContentDecompressorin die Pipeline hängt. - Client:
WebClientauf Reactor Netty mit.compress(true)hängt denHttpContentDecompressorein. Eine Brotli-Antwort eines fremden Servers wird dann nativ entpackt, auch wenn manbrgar nicht angefragt hat. - gRPC-Java mit Netty-Transport und andere Netty-basierte Bibliotheken bitte genauso prüfen.
Wenn brotli4j drin ist, auf 1.24.0 heben (siehe oben). Wer Brotli gar nicht braucht, schließt brotli4j stattdessen per <exclusion> aus. Netty fällt dann still auf gzip/deflate zurück.
Jetty (spring-boot-starter-jetty)
- Jetty bis 12.0 kennt nur gzip (
GzipHandler) und ist nicht betroffen. - Jetty 12.1 hat das neue Modul
org.eclipse.jetty.compression:jetty-compression-brotli. Es hängt an brotli4j (12.1.1 nutzt brotli4j 1.17.0). DerCompressionHandlerkann damit auch Request-Bodies entpacken. Wer dieses Modul eingebunden hat, ist betroffen und muss brotli4j auf 1.24.0 heben (siehe oben) oder das Modul entfernen. - Für den Jetty-
HttpClientgilt dasselbe, sobald das Brotli-Modul geladen ist.
libbrotli im Base-Image
Scanner melden libbrotli1 (Debian, Ubuntu), brotli-libs (Alpine) oder brotli (RHEL, UBI) in fast jedem Java-Image, weil curl oder libfreetype die Bibliothek mitziehen. Für HTTP nutzt der Java-Prozess diese Bibliothek nicht:
- Die JVM selbst kann kein Brotli. Tomcat, Netty, Jetty und der JDK-
HttpClientrufen die System-Bibliothek nicht auf. - Nativen C-Code erreicht Java nur über JNI. Dafür braucht es eine Bridge in den Maven-Abhängigkeiten, praktisch immer brotli4j, selten ältere Bindings wie jbrotli. Ohne diese Bridge entpackt der Java-Prozess kein Brotli mit dem verwundbaren C-Decoder, egal welche
libbrotliim Image liegt. - brotli4j nutzt die OS-Bibliothek ebenfalls nicht, sondern bringt eine eigene Kopie im JAR mit. Ein OS-Update repariert brotli4j deshalb nicht, und ein brotli4j-Update repariert die OS-Bibliothek nicht.
- Im Image bleiben die Tools, die die OS-Bibliothek nutzen, vor allem
curl. libcurl entpackt aber nur mit--compressed(bzw. gesetztemCURLOPT_ACCEPT_ENCODING). Kritisch ist das nur, wenn ein Skript im Container damit fremde Server abfragt. Ein Healthcheck gegenlocalhostist es nicht. - Ausnahme Schriften: Rendert die Anwendung Schriften (AWT, PDF- oder Bildgenerierung), lädt das JDK
libfreetype, und die hängt anlibbrotlidec. Die Bibliothek liegt dann im Prozess. Freetype entpackt damit nur WOFF2-Schriften. Erreichbar ist der Decoder also nur, wenn die Anwendung Schriften aus fremder Quelle lädt. Nach meiner Einschätzung ist das kein realistischer Angriffsweg. Wer Font-Uploads verarbeitet, aktualisiert das Image trotzdem zuerst.
Ob der laufende Java-Prozess Brotli geladen hat, zeigt /proc/<pid>/maps. Bei exec java im Entrypoint ist das PID 1:
docker exec <container> grep -i brotli /proc/1/maps
# kein Treffer: kein nativer Brotli-Decoder im Prozess
# Pfad unter /usr/lib: OS-Bibliothek, meist über libfreetype (siehe oben)
# Pfad unter /tmp: von brotli4j entpackte eigene Kopie, brotli4j auf 1.24.0 heben
Die Maven-Abhängigkeiten prüft man wie oben mit mvn dependency:tree oder unzip -l auf dem Fat-JAR.
Container und Plattform rund um Spring Boot
Auch reine Java-Dienste laufen selten allein:
- Base-Images neu bauen und das Betriebssystem aktualisieren (
apt-get upgrade), weillibbrotliundcurlaus dem OS kommen. Gefixte Pakete gibt es bisher nur für Debian bookworm (1.0.9-2+deb12u1, DLA-4855-1), trixie (1.1.0-2+deb13u1, DSA-6582-1) und sid (1.2.0-4.1). Debian forky ist am 26.10. noch offen. Für Red Hat, Ubuntu, SUSE und Amazon Linux gab es am 24.10. noch keine Pakete, einen neueren Stand habe ich nicht gefunden. Dort hilft das OS-Update noch nicht. - [update] Neuer Stand der Distributionen am 27.10.:
- Ubuntu hat am 26.10. USN-8956-1 veröffentlicht.
brotliist gefixt in jammy (1.0.9-2ubuntu0.1), noble (1.1.0-2ubuntu0.1), resolute (1.2.0-3ubuntu0.1) und stonking (1.2.0-4ubuntu0.1). focal und älter sind noch nicht bewertet. Ubuntusnodejs-Pakete nutzen die System-Bibliothek und sind laut Ubuntu nicht betroffen, nur focal braucht noch einen Fix. - Amazon Linux 2023 hat
brotli(ALAS2023-2026-3334) undnodejs24(ALAS2023-2026-3330) mit Datum 24.10. gefixt. Fürnodejsundnodejs20plant Amazon keinen Fix. - SUSE hat bisher nur openSUSE Tumbleweed gefixt (
brotli1.2.1-1.1,nodejs2424.22.1-1.1). Für SLES 15 SP6 und SP7 istnodejs2222.23.4 in QA.brotliundpython-Brotlisind in SLES und Leap noch offen. - Red Hat führt
brotliin RHEL 8, 9 und 10 weiter als betroffen, Errata gibt es keine. Gefixt sind nur die Red Hat Hardened Images (RHSA-2026:87420). Dienodejs-Pakete von RHEL 8 und 10 führt Red Hat als nicht betroffen. - Debian forky ist weiter offen.
- Ubuntu hat am 26.10. USN-8956-1 veröffentlicht.
- [update 2] Neuer Stand der Distributionen am 27.10.:
- Red Hat hat am 26.10.
brotligefixt: RHEL 8 (1.0.6-5.el8_10, RHSA-2026:90501), RHEL 9 (1.0.9-10.el9_8.1, RHSA-2026:90495) und RHEL 10 (1.1.0-8.el10_2.1, RHSA-2026:90449). - Korrektur zum ersten Update: Bei
nodejsführt Red Hat nurnodejs:22und die Pakete in RHEL 10 als nicht betroffen.nodejs:24ist in RHEL 8 und 9 betroffen, in RHEL 9 auchnodejs:26, einen Fix gibt es dafür noch nicht. - Ebenfalls betroffen laut Red Hat:
istio-proxyin OpenShift Service Mesh 3 und RHCOS 8/9 in OpenShift 4. - Red Hat bewertet die Lücke nur als Important (CVSS 3.1 8.1). Begründung: ASLR, NX, FORTIFY_SOURCE und SELinux erschweren zuverlässige Code Execution, und es gibt keinen öffentlichen PoC, der zuverlässig RCE erreicht.
- Oracle Linux hat am 26. und 27.10.
brotlifür OL 8, 9 und 10 gefixt (OL 9:1.0.9-10.0.1.el9_8, ELSA-2026-500513), dazu dienodejs-Pakete. - Ubuntu, SUSE, Amazon Linux und Debian forky: unverändert.
- Red Hat hat am 26.10.
- [update 3] Neuer Stand der Distributionen am 28.10.:
- Ubuntu hat am 27.10. zusätzlich USN-8956-2 veröffentlicht.
brotliin focal, bionic und xenial ist weiter nicht bewertet,nodejsin focal weiter verwundbar. - SUSE: Für SLES 15 SP7 sind jetzt auch
brotli(1.0.7-150200.3.8.1) undnodejs24(24.22.1-150700.15.21.1) in QA. Für SLES 15 SP6-LTSS sindbrotliundnodejs22in Arbeit.python-Brotliist in SLES weiter offen, openSUSE Leap 16.0 komplett. Tumbleweed hat jetzt auchpython-Brotli1.2.1. - Red Hat: Für
nodejs:24(RHEL 8/9) undnodejs:26(RHEL 9) gibt es weiter keinen Fix. Red Hat verweist inzwischen auf das Bulletin RHSB-2026-015. - Debian: unverändert. forky
brotliist offen,nodejsin bookworm, trixie und forky verwundbar.
- Ubuntu hat am 27.10. zusätzlich USN-8956-2 veröffentlicht.
- [update 4] Neuer Stand der Distributionen am 02.11.:
- Red Hat hat am 29.10.
nodejs:24für RHEL 8 (RHSA-2026:92376) und RHEL 9 (RHSA-2026:92378) gefixt, dazudotnet8.0in RHEL 8, 9 und 10. Offen ist nochnodejs:26in RHEL 9. - Korrektur zum zweiten Update:
istio-proxyin OpenShift Service Mesh 3 führt Red Hat jetzt als nicht betroffen. RHCOS 8/9 in OpenShift 4 bleibt betroffen. - Ubuntu hat
brotlijetzt auch für focal (1.0.7-6ubuntu0.1+esm1), bionic und xenial gefixt, allerdings nur über ESM mit Ubuntu Pro.nodejsin focal nutzt die mitgebündelte Kopie und ist weiter verwundbar. Die .NET-Pakete sind mit USN-8958-1 vom 29.10. gefixt. - SUSE:
brotli(1.0.7-150200.3.8.1) ist für SLES 15 SP6 und SP7 veröffentlicht, für SP6 auchnodejs2222.23.4. Für SP7 sindnodejs22,nodejs24undpython-Brotliweiter in QA. openSUSE Leap 16.0 hatpython313-Brotli1.2.1,brotliund dienodejs-Pakete sind dort offen. - Debian: forky
brotliist weiter offen,nodejsin bookworm, trixie und forky weiter als verwundbar geführt. Der Tracker merkt inzwischen an, dassnodejsundpython-brotlicffiin Debian die System-Bibliothek nutzen. sid hatnodejs24.22.2. - Amazon Linux und Oracle Linux habe ich nicht neu geprüft.
- Red Hat hat am 29.10.
- Service Mesh prüfen: Envoy und Istio sind betroffen (siehe eigenen Abschnitt Istio und Envoy).
- Node- oder Python-Tools im selben Image (Build-Steps, Sidecars) mit aktualisieren.
Istio und Envoy
Warum beide betroffen sind
Envoy ist ein in C++ geschriebener Proxy und linkt die native Google-Brotli-Bibliothek (decode.c) statisch ins eigene Binary. Der verwundbare Decoder steckt damit fest im Envoy-Binary jeder betroffenen Version. Das ist dieselbe Ursache wie bei Node und Python, nur in einem anderen Wirt.
Istios Data Plane ist Envoy: Jeder Sidecar (Container istio-proxy) und jedes Gateway (Ingress/Egress) läuft als Envoy-Prozess. Die Bibliothek liegt also in jedem Proxy-Pod.
Entscheidend ist aber der Unterschied zwischen „Code ist vorhanden" und „Code wird erreicht":
- Der Overflow greift nur, wenn Envoy tatsächlich Brotli entpackt. Das macht der HTTP-Filter
envoy.filters.http.decompressormit der Brotli-Extension (envoy.extensions.compression.brotli.decompressor.v3.Brotli). - In Istio ist das nicht Default. Es wird typischerweise per
EnvoyFiltereingeschaltet. Ohne eine solche Konfiguration ist der verwundbare Pfad nicht erreichbar. - Reines ausgehendes Komprimieren (
compressor) ruft den Decoder nicht auf und ist nicht der verwundbare Pfad. - Entpackt wird: eingehende Request-Bodies mit
Content-Encoding: brund Antworten von Upstreams. Beides erreicht ein nicht authentifizierter Angreifer.
Kurz: Binary vorhanden = potenziell betroffen. Decompressor konfiguriert = tatsächlich exponiert.
Prüfen, ob man betroffen ist
Zwei Fragen, zwei Checks. Da viele Istio-Versionen im Einsatz sind, zuerst den Überblick über das ganze Mesh verschaffen.
1. Welche Istio-/Envoy-Versionen laufen wo?
# Control-Plane- und Data-Plane-Versionen im Mesh
istioctl version
# Jeder Proxy mit seiner Istio-Version (zeigt alle Sidecars + Gateways)
istioctl proxy-status
# Envoy-Version eines konkreten Proxys
istioctl proxy-config bootstrap <pod>.<namespace> -o json | grep -i build_version
# oder direkt im Pod
kubectl exec <pod> -c istio-proxy -- pilot-agent request GET server_info | jq -r .version
Betroffene Envoy-Versionen: 1.39.2, 1.38.5, 1.37.7, 1.36.11 und jeweils älter. Gefixt in 1.40.0, 1.39.3, 1.38.6, 1.37.8, 1.36.12 (1.36 ist unsupported).
2. Ist Brotli-Decompression überhaupt konfiguriert?
# EnvoyFilter, die Brotli einschalten (clusterweit)
kubectl get envoyfilter -A -o yaml | grep -i brotli
# Laufende Konfiguration eines Proxys durchsuchen
istioctl proxy-config all <pod>.<namespace> -o json | grep -i brotli
Auf die Treffer achten:
...brotli.decompressor...→ verwundbarer Pfad aktiv → betroffen.- Nur
...brotli.compressor...oder gar kein Treffer → über diese Lücke nicht exponiert.
Gateways nicht vergessen: dieselben Checks gegen die Ingress-/Egress-Gateway-Pods laufen lassen.
Was tun
- Istio auf 1.29.9, 1.30.6 oder 1.31.2 aktualisieren. 1.29 ist end of life, also besser auf eine unterstützte Linie wechseln. Der Fix kommt über den Envoy-Bump, ein Istio-Upgrade reicht, Envoy wird nicht separat installiert.
- Wo ein Decompressor konfiguriert ist und das Upgrade nicht sofort geht: als Übergangslösung den
EnvoyFiltermit der Brotli-Decompression entfernen, oder eingehend am Gateway Requests mitContent-Encoding: brablehnen (siehe Übergangslösung am Proxy). - Wo nichts entpackt wird, ist man nicht exponiert. Trotzdem beim nächsten Turnus patchen, weil das verwundbare Binary vorhanden bleibt und eine spätere Konfigurationsänderung den Pfad aktivieren würde.
Kann man Brotli in Istio deaktivieren?
Einen globalen „Brotli aus"-Schalter gibt es nicht. Die Brotli-Bibliothek ist fest ins Envoy-Binary kompiliert; rausbekommt man sie nur per Envoy-Rebuild, also praktisch per Istio-Upgrade. Abschalten lässt sich nur der Pfad, der sie erreicht:
- Default ist bereits „aus". Istio entpackt Brotli nicht von sich aus. Wenn der Check oben keinen
decompressorfindet, ist nichts zu deaktivieren. - Falls ein Decompressor konfiguriert ist, den auslösenden
EnvoyFilterentfernen (kubectl delete envoyfilter …) oder die Brotli-Decompression darin herausnehmen. Envoy fällt dann auf gzip/deflate zurück.
Als zusätzliche Absicherung eingehend am Ingress-Gateway Content-Encoding: br hart ablehnen, unabhängig von sonstiger Konfiguration:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: reject-brotli
namespace: istio-system
spec:
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 ce = handle:headers():get("content-encoding")
if ce and string.find(string.lower(ce), "br", 1, true) then
handle:respond({[":status"] = "415"}, "brotli not accepted")
end
end
Das deckt nur die eingehende Richtung ab. Antworten von Upstreams werden ohnehin nur dann entpackt, wenn dafür ein Response-Decompressor konfiguriert ist — den gegebenenfalls genauso entfernen. Für Sidecars statt des Gateways context: SIDECAR_INBOUND verwenden. Das bleibt eine Übergangslösung; der saubere Fix ist das Istio-Upgrade.
Node.js
Node.js bündelt Brotli direkt. Betroffen sind jedes eingebaute fetch(), zlib.brotliDecompress*, body-parser und damit Express. Es gibt keinen Konfigurationsschalter, nur das Update.
- Node aktualisieren auf 22.23.4, 24.22.1 oder 26.12.1. Node 20 und älter sowie 23.x und 25.x bekommen keinen Patch. Diese Versionen müssen auf eine gepatchte LTS-Version.
- Docker-Images neu bauen (
FROM node:...mit gepatchtem Tag) und neu deployen. Danach im laufenden Containernode -vprüfen. CI-Runner nicht vergessen. Dienodejs-Pakete von Debian (bookworm bis sid) führt der Debian-Tracker am 26.10. noch als verwundbar. - Bun auf 1.4.4 aktualisieren und mit Bun kompilierte Executables neu bauen.
- Bis zum Update
br-Requests vor dem Body-Parser ablehnen:
app.use((req, res, next) => {
if (/\bbr\b/i.test(req.headers['content-encoding'] ?? '')) {
return res.status(415).end();
}
next();
});
Das schützt nur eingehend. Gegen bösartige Antworten bei ausgehendem fetch() hilft nur das Update.
[update] Debian sid hat seit 26.10. das gefixte nodejs 24.22.1 (24.22.1+dfsg+~cs24.19.2-1). bookworm, trixie und forky sind weiter verwundbar.
[update] Laut ELLIO meldet process.versions.brotli auch in gepatchten Builds 1.2.0. Ob ein Build gefixt ist, zeigt nur die Node-Version (node -v).
[update 2] Oracle Linux hat am 26.10. die nodejs-Pakete für OL 8, 9 und 10 gefixt. In RHEL 8 und 9 ist nodejs:24 noch ungefixt, in RHEL 9 auch nodejs:26 (siehe Container und Plattform).
[update 4] Red Hat hat nodejs:24 in RHEL 8 und 9 am 29.10. gefixt, offen ist nur noch nodejs:26 in RHEL 9. Node 26.13.0 vom 28.10. ist das erste reguläre Release nach dem Fix und enthält ihn ebenfalls. Debian sid hat inzwischen nodejs 24.22.2.
Python
Betroffen sind die Pakete Brotli (bis 1.2.0) und brotlicffi (1.2.0.x). requests/urllib3, httpx (mit Extra brotli), aiohttp und Scrapy laden sie automatisch, sobald sie installiert sind.
pip list 2>/dev/null | grep -i brotli
Brotliauf 1.2.1 undbrotlicffiauf 1.2.1.0 aktualisieren.- Images und Wheels neu bauen, Prozesse neu starten.
- Falls das nicht sofort geht, beide Pakete deinstallieren und Extras entfernen, die sie wieder installieren (
httpx[brotli],urllib3[brotli],aiohttp[speedups]). Die HTTP-Clients fallen dann auf gzip zurück.
[update] Debian sid hat seit 26.10. python-brotlicffi 1.2.1.0 (1.2.1.0+ds-1). trixie und forky sind noch verwundbar. Das Debian-Paket python3-brotli baut Debian aus dem Quellpaket brotli, es ist mit dessen Fix erledigt (siehe Container und Plattform).
.NET
Microsoft hat am 25.10. Fixes veröffentlicht (dotnet/announcements#494, CVSS 3.1 8.1). System.IO.Compression.Brotli (BrotliStream, BrotliDecoder) ruft per P/Invoke eine mitgelieferte native Kopie von Google Brotli auf (.NET 10: Version 1.1.0). Betroffen sind alle Plattformen und Architekturen, .NET Framework nicht. Einen Crash unter .NET hat bisher niemand öffentlich gezeigt.
| .NET | Betroffen | Gepatchte Runtime | Gepatchtes SDK |
|---|---|---|---|
| 8.0 | < 8.0.33 | 8.0.33 | 8.0.133, 8.0.427 |
| 9.0 | < 9.0.22 | 9.0.22 | 9.0.123, 9.0.320 |
| 10.0 | < 10.0.14 | 10.0.14 | 10.0.114, 10.0.403 |
| 11.0 Preview | < 11.0.0-rc.3.26522.148 | 11.0.0-rc.3.26522.148 | 11.0.100-rc.3.26522.148 |
Weil .NET seine eigene Kopie mitbringt, hilft ein OS-Update von libbrotli bei den offiziellen Microsoft-Builds nicht. Distributions-Builds aus source-build können stattdessen die System-Bibliothek nutzen. Wer .NET selbst aus den GitHub-Quellen baut, ist noch betroffen, bis die Fixes in die öffentlichen Branches portiert sind. dotnet/runtime#136422 ist dafür wieder offen.
Erreicht wird der Decoder nur, wenn Brotli tatsächlich entpackt wird:
- ASP.NET Core Request Decompression (
AddRequestDecompression()/UseRequestDecompression()) entpackt eingehende Bodies mitContent-Encoding: br. Kestrel tut das ohne diese Middleware nicht. HttpClientmitAutomaticDecompression = DecompressionMethods.BrotlioderDecompressionMethods.Allentpackt Brotli-Antworten fremder Server. Default istNone.- Eigener Code, der
BrotliStreammitCompressionMode.DecompressoderBrotliDecoderauf fremde Daten anwendet. - Response Compression (
AddResponseCompression()) komprimiert nur und ist nicht der verwundbare Pfad.
Ein installiertes Paket allein macht eine Anwendung laut Microsoft nicht angreifbar.
dotnet --list-runtimes
dotnet --list-sdks
grep -rnE "RequestDecompression|DecompressionMethods\.(Brotli|All)|BrotliStream|BrotliDecoder" --include=*.cs .
Update:
- Runtime bzw. SDK auf die gepatchte Version heben, Docker-Images neu bauen und Anwendungen neu starten.
- Self-contained Apps mit der neuen Runtime neu bauen und neu deployen, weil sie die Runtime mitbringen.
- NativeAOT-Apps: SDK und explizite Referenzen auf
Microsoft.DotNet.ILCompilerund die Runtime-Packs aktualisieren, dann neu publishen. Ein Update der Shared Runtime ersetzt den Decoder nicht, der schon ins Executable gelinkt ist. - Direkte Paketreferenzen auf die gepatchten Versionen heben.
Bis zum Update:
- In der Request Decompression den Brotli-Provider entfernen:
services.AddRequestDecompression(o => o.DecompressionProviders.Remove("br")); - Bei
HttpClientnurDecompressionMethods.GZip | DecompressionMethods.Deflatesetzen stattAll. - Eingehend
bram Proxy ablehnen (siehe Übergangslösung am Proxy).
Microsoft rät, dabei keine Decompression neu einzuschalten, die die Anwendung bisher nicht nutzt. Automatisches Entpacken birgt auch ohne Brotli ein DoS-Risiko.
Der offene PR dotnet/runtime#136430 ersetzt den nativen Code durch eine verwaltete C#-Portierung von Brotli 1.2.1. Laut Autor ist das ein Experiment und kein Security-Fix.
[update] Der PR ist seit 26.10. ohne Merge geschlossen.
[update 2] Der main-Branch von dotnet/runtime nutzt seit 26.10. Brotli 1.1.1 (dotnet/runtime#136471). Wer aus main baut, hat damit den Fix. #136422 ist weiter offen.
[update 4] Ubuntu (USN-8958-1) und Red Hat haben am 29.10. ihre dotnet8.0-Pakete gefixt. .NET 9, 10 und 11 nutzen in RHEL die System-Bibliothek, dort reicht das brotli-Update. #136422 ist am 02.11. weiter offen.
Grafana-Stack
Grafana hat bis 26.10. kein Advisory zu CVE-2026-111497 veröffentlicht. Der Grafana-Server ist nach meiner Einschätzung nicht betroffen, das Image des Grafana Image Renderer schon. Alloy, Tempo und Loki sind ebenfalls nicht betroffen (siehe Alloy, Tempo und Loki).
Grafana-Server
- Das Backend ist in Go geschrieben. Brotli kommt über
github.com/andybalholm/brotli(v1.2.3) ins Projekt. Das ist eine reine Go-Portierung ohne nativen Code. Go prüft wie die JVM jeden Array-Zugriff, ein Speicher-Overflow kann so nicht entstehen. Das ist meine Einschätzung, eine Aussage von Grafana dazu habe ich nicht gefunden. - Das Frontend wird beim Build mit Node gebaut und als statisches Bundle ausgeliefert. Im fertigen Image läuft kein Node.js.
- Das Alpine-Image installiert
curl, undlibcurlziehtbrotli-libsmit. Der Grafana-Prozess nutzt diese Bibliothek nicht, nurcurlim Container. Scanner melden sie trotzdem. - Backend-Plugins von Drittanbietern laufen als eigene Binaries. Plugins, die nativen Code per cgo einbinden oder nicht in Go geschrieben sind, einzeln prüfen.
Grafana Image Renderer
- Der Renderer ist in Go geschrieben und steuert einen Chromium. Das Image basiert auf
debian:trixieund installiert Chromium aus den Debian-Paketen. - Das aktuelle Release v5.12.9 vom 23.10. enthält noch
libbrotli1 1.1.0-2+b7und ist damit verwundbar. Gefixt ist1.1.0-2+deb13u1(DSA-6582-1). PR #1069 baut das Image mit dem gefixten Paket neu, ist am 26.10. aber noch nicht gemergt. - [update] Am 27.10. ist PR #1069 weiter offen. Ein neueres Release als v5.12.9 gibt es nicht.
- [update 3] Grafana hat am 28.10. v5.12.10 veröffentlicht. PR #1072 baut das Image auf
debian:trixie-20261027mit frischemapt-get upgradeneu. Geprüft im Imagegrafana/grafana-image-renderer:v5.12.10(amd64):libbrotli1 1.1.0-2+deb13u1,chromium 156.0.8078.47-1~deb13u1. PR #1069 ist damit überholt. broccoli2shell.com führt Chromium als bereits gefixt, nennt aber keine Version. - Das Debian-Paket
chromiumhängt nicht vonlibbrotli1ab und nutzt damit eine eigene, mitkompilierte Brotli-Kopie. Chromium entpackt Brotli bei HTTP-Antworten mitContent-Encoding: brund in WOFF2-Schriften. Ob diese Kopie betroffen und schon gefixt ist, habe ich nicht gefunden. Der Debian-Tracker führt Chromium bei dieser CVE nicht. - [update 3] Chromium hat den Fix seit Version 148. Laut
third_party/brotli/README.chromiumsteht Brotli dort auf Revisioncfa184avom 18.03.2026. Diese Revision enthält den Upstream-Fix0ed4268vom 27.02.2026, den Brotli 1.2.1 als Cherry-Pick übernommen hat. Chromium 156 in v5.12.10 ist damit gefixt. - Der Renderer lädt normalerweise nur Grafana-Seiten. Bindet ein Dashboard aber fremde Inhalte ein (Bilder oder iframes im Text-Panel, externe Webfonts), entpackt Chromium deren Antworten.
- Ältere Versionen des Renderers liefen als Node-Plugin. Wer die noch nutzt, hat zusätzlich Node.js mit gebündeltem Brotli im Prozess (siehe Node.js).
Grafana und Renderer prüfen
# Grafana-Image (Alpine): OS-Bibliothek
docker run --rm --entrypoint sh grafana/grafana -c 'apk info -v | grep -i brotli'
# Renderer-Image: libbrotli1 muss 1.1.0-2+deb13u1 oder neuer sein
docker run --rm --entrypoint sh grafana/grafana-image-renderer -c 'dpkg -l | grep -iE "brotli|chromium"'
Was tun bei Grafana und Renderer
- Bis ein gefixtes Renderer-Release erscheint, das Image selbst nachziehen:
FROM grafana/grafana-image-renderer:v5.12.9
USER root
RUN apt-get update \
&& apt-get install -y --only-upgrade --no-install-recommends libbrotli1 chromium chromium-shell chromium-driver chromium-sandbox \
&& rm -rf /var/lib/apt/lists/*
USER 65532
- Den Renderer nur intern erreichbar machen, sodass nur Grafana ihn aufruft, und das Auth-Token (
rendering.renderer_tokenin Grafana) setzen. - Keine fremden Inhalte in Dashboards einbinden, die gerendert werden, solange der Chromium-Status unklar ist.
- Grafana-Server und dessen Image beim nächsten Turnus aktualisieren. Nötig ist das wegen dieser Lücke nicht.
[update 3] Statt des eigenen Dockerfiles reicht jetzt das Update auf grafana/grafana-image-renderer:v5.12.10. Die Tags auf Docker Hub haben ein v vorne, 5.12.9 ohne v gibt es nicht. Das Dockerfile oben ist entsprechend korrigiert.
Alloy, Tempo und Loki
Nach meiner Einschätzung nicht betroffen. Eine Aussage von Grafana dazu habe ich nicht gefunden. Geprüft in den Images am 28.10.:
| Image | Brotli im Binary | cgo | Basis | libbrotli im Image | |
|---|---|---|---|---|---|
| Alloy | grafana/alloy 1.21.2 | andybalholm/brotli v1.2.4 | an, linkt nur libc | Ubuntu 24.04 | nein |
| Tempo | grafana/tempo:latest (3.0.0) | andybalholm/brotli v1.1.1 | aus | distroless | nein |
| Loki | grafana/loki 3.7.9 | andybalholm/brotli v1.2.6 | aus | distroless | nein |
- Alle drei sind in Go geschrieben und nutzen wie der Grafana-Server nur die reine Go-Portierung
github.com/andybalholm/brotli. Die cgo-Bindings von Google (github.com/google/brotli/go/cbrotli) stehen weder in den Binaries noch imgo.modaufmain. - Alloy ist mit cgo gebaut, linkt aber nur
libc,libpthreadundlibdl. Tempo und Loki sind statisch ohne cgo gebaut. - In keinem der drei Images liegt
libbrotli. Scanner sollten hier also nichts melden. grafana/tempo:latestzeigte am 28.10. noch auf 3.0.0, das aktuelle Release ist 3.1.1.
# Binary aus dem Image holen (Alloy: /usr/bin/alloy, Tempo: /tempo, Loki: /usr/bin/loki)
cid=$(docker create grafana/loki:3.7.9)
docker cp $cid:/usr/bin/loki /tmp/loki && docker rm $cid
go version -m /tmp/loki | grep -iE "brotli|CGO_ENABLED"
# erwartet: nur github.com/andybalholm/brotli, kein cbrotli
Was tun: Nichts wegen dieser Lücke.
MySQL
Oracle hat bis 27.10. nichts zu CVE-2026-111497 veröffentlicht. Der MySQL-Server ist nach meiner Einschätzung nicht betroffen.
- MySQL komprimiert das Client-Protokoll nur mit zlib und zstd, Brotli gibt es dort nicht.
mysqldund die Standard-Plugins linkenlibbrotlinicht (geprüft mitlddinmysql:8.08.0.46 undmysql:9.79.7.2). - Die curl-Kopie im Quellcode (
extra/curl) baut MySQL ohne Brotli (set(HAVE_BROTLI OFF)). Eine eigene Kopie vondecode.cbringt MySQL nicht mit. - Die offiziellen Images (Oracle Linux 9) enthalten trotzdem
libbrotli1.0.9 aus dem OS, gezogen übercurl. Gefixte Pakete für Oracle Linux gibt es noch nicht. Scanner melden sie deshalb. - Nur zwei Komponenten im Image laden die Bibliothek über libcurl: MySQL Shell (
mysqlsh) und unter 9.x die Telemetrie-Komponente (component_telemetry). Bei uns ist die Telemetrie nicht installiert, undmysqlshläuft nur lokal als SQL-Client und lädt nichts von fremden Servern. Der Decoder ist damit nicht erreichbar.
docker run --rm --entrypoint sh mysql:9.7 -c 'rpm -q libbrotli; ldd /usr/sbin/mysqld | grep -i brotli'
-- Telemetrie-Komponente geladen?
SELECT * FROM mysql.component;
Was tun: Kein Notfall-Patch nötig. Die Images neu bauen, sobald Oracle Linux ein gefixtes libbrotli hat.
[update 2] Oracle Linux 9 hat seit 26.10. das gefixte libbrotli-1.0.9-10.0.1.el9_8 (ELSA-2026-500513). Die Images können jetzt neu gebaut werden. Ob Oracle die offiziellen mysql-Images schon neu gebaut hat, habe ich nicht geprüft, also nach dem Build mit rpm -q libbrotli kontrollieren.
OpenSearch
Ein Advisory des OpenSearch-Projekts zu CVE-2026-111497 habe ich bis 28.10. nicht gefunden. Der OpenSearch-Server ist nach meiner Einschätzung nicht betroffen, OpenSearch Dashboards schon. Geprüft habe ich die Images opensearchproject/opensearch 2.19.5 und 3.9.0 sowie opensearchproject/opensearch-dashboards 2.19.5 und 3.9.0.
OpenSearch-Server
- OpenSearch ist in Java geschrieben und nutzt Netty. Netty bringt die Klasse
BrotliDecodermit, entpackt Brotli aber nur, wenn brotli4j auf dem Classpath liegt (siehe Netty). Weder der Kern noch die mitgelieferten Plugins bringen brotli4j mit. Das gilt auch für die geshadete Netty-Kopie intransport-grpc(3.9.0). - Apache HttpClient 5 und commons-compress in den Plugins enthalten nur Java-Code.
- OpenSearch 3.9.0 bringt mit
netty-codec-native-quicnative Bibliotheken mit. Darin liegt nur die Lizenzdatei von brotli4j, die Bibliotheklibnetty_quiche42selbst enthält keinen Brotli-Decoder. - Die Images basieren auf Amazon Linux 2023 und enthalten kein
libbrotli.curl-minimalkommt ohne Brotli aus, und das mitgelieferte JDK bringt ein eigeneslibfreetypeohne Brotli mit. Scanner sollten hier nichts melden.
Plugins von Drittanbietern einzeln prüfen:
# kein Treffer: kein brotli4j
docker run --rm --entrypoint sh opensearchproject/opensearch:3.9.0 -c 'ls -R /usr/share/opensearch | grep -i brotli4j'
Was tun: Nichts wegen dieser Lücke.
OpenSearch Dashboards
OpenSearch Dashboards ist eine Node-Anwendung und bringt ein eigenes Node-Binary mit (node/bin/node). Node bündelt Brotli, ein OS-Update hilft deshalb nicht. Stand 28.10. ist keine veröffentlichte Version gefixt:
| Dashboards | Mitgeliefertes Node | Status |
|---|---|---|
| 2.19.x (auch 2.19.6) | 18.19.0 | Node 18 bekommt keinen Patch |
| 3.0 bis 3.4 | 20.18.3 | Node 20 bekommt keinen Patch |
| 3.5 und 3.6 | 22.22.0 | verwundbar |
| 3.7 | 22.22.3 | verwundbar |
| 3.8 und 3.9 | 22.23.0 | Bump auf 22.23.4 in main gemergt (#13037, 22.10.), Backport auf 3.9 (#13048) offen, noch kein Release |
Das Image von 2.19.5 enthält zusätzlich ein Fallback-Node 14.21.3 (node/fallback), das nur startet, wenn das Haupt-Binary auf dem System nicht läuft.
Wo der Decoder erreicht wird:
- Eingehend nicht. Dashboards läuft auf hapi, und hapi entpackt Request-Bodies nur mit gzip und deflate (
@hapi/subtext). BeiContent-Encoding: brignoriert hapi den Header und liest den Body unentpackt. Getestet mit 3.9.0: Ein POST mitContent-Encoding: brund unkomprimiertem JSON geht mit 200 durch, der Brotli-Decoder läuft dabei nicht. - Ausgehend schon. node-fetch 2.7.0 und axios 1.12.2 entpacken Brotli-Antworten automatisch. Welche Plugins damit wohin verbinden, habe ich nicht im Einzelnen geprüft.
- Im Image von 2.19.5 liegt
libbrotli1.0.9-4.amzn2023.0.2, gezogen überfreetype. Gefixt ist1.1.0-1.amzn2023.0.2(ALAS2023-2026-3334), das aktuelle Image von 3.9.0 (Stand 26.10.) hat es schon. Node nutzt diese Bibliothek nicht, Scanner melden die alte Version trotzdem.
docker run --rm --entrypoint sh opensearchproject/opensearch-dashboards:3.9.0 -c '/usr/share/opensearch-dashboards/node/bin/node -v; rpm -q libbrotli'
Gefixt ist erst Node 22.23.4 (siehe Node.js). process.versions.brotli hilft hier nicht.
Was tun:
- Auf das erste 3.9.x-Release mit Node 22.23.4 aktualisieren, sobald es erscheint.
- 2.19 und 3.0 bis 3.4 bekommen über ihre Node-Version keinen Fix. Upgrade auf die gepatchte 3.x-Linie planen.
- Für 3.5 bis 3.9 lässt sich bis dahin ein gepatchtes Node einsetzen.
bin/use_nodenimmtOSD_NODE_HOMEvor dem mitgelieferten Binary. Von 22.23.0 auf 22.23.4 ist das ein Patch-Sprung innerhalb derselben Linie:
FROM opensearchproject/opensearch-dashboards:3.9.0
USER root
# x64; für arm64 linux-arm64 einsetzen
RUN cd /tmp \
&& curl -fsSLO https://nodejs.org/dist/v22.23.4/node-v22.23.4-linux-x64.tar.gz \
&& curl -fsSL https://nodejs.org/dist/v22.23.4/SHASUMS256.txt | grep " node-v22.23.4-linux-x64.tar.gz$" | sha256sum -c - \
&& tar -xzf node-v22.23.4-linux-x64.tar.gz -C /opt \
&& rm node-v22.23.4-linux-x64.tar.gz
ENV OSD_NODE_HOME=/opt/node-v22.23.4-linux-x64
USER 1000
Getestet mit 3.9.0 gegen OpenSearch 3.9.0: Dashboards läuft mit /opt/node-v22.23.4-linux-x64/bin/node und meldet Status green.
- Ausgehenden Traffic von Dashboards per Egress-Regel oder Proxy auf bekannte Ziele beschränken. Ein Proxy, der Antworten mit
Content-Encoding: brverwirft, hilft ebenfalls (siehe Übergangslösung am Proxy).
[update 4] Stand 02.11.: Der Backport #13048 ist weiter offen. Das neueste Release ist weiter 3.9.0 vom 12.10.
Elastic Stack
Ein Advisory von Elastic zu CVE-2026-111497 habe ich bis 28.10. nicht gefunden. Elasticsearch und Logstash sind nach meiner Einschätzung nicht betroffen, Kibana schon. Geprüft habe ich die Images elasticsearch, kibana und logstash 9.4.8 von docker.elastic.co.
Elasticsearch
- Elasticsearch ist wie OpenSearch eine Java-Anwendung auf Netty, ohne brotli4j. Der Build führt die brotli4j-Klassen ausdrücklich als fehlend (
thirdPartyAuditinmodules/transport-netty4/build.gradle). - Das Modul
esql-datasource-brotliliest Brotli-Dateien mit dem reinen Java-Decoderorg.brotli:dec0.1.2 und ist damit unkritisch. - Das Image basiert auf RHEL 9.8 und enthält kein
libbrotli.
Was tun: Nichts wegen dieser Lücke.
Kibana
- Kibana 9.4.8 bringt Node 24.21.0 mit (
node/defaultundnode/glibc-217) und ist damit verwundbar. Laut elastic/kibana#299985 gilt das auch für 9.5.5 und 8.19.23. 9.3 bringt Node 22.23.1 mit. - Elastic hat Node 24.22.1 am 21.10. in die Branches 9.5, 9.4 und 8.19 gemergt und das Issue am 27.10. geschlossen. Ein Release gibt es noch nicht, die neuesten sind 9.5.5, 9.4.8 und 8.19.23 vom 06.10. Ob 9.3 noch ein Update bekommt, ist offen.
- Eingehend ist der Decoder nicht erreichbar. Kibana läuft wie Dashboards auf hapi ohne Brotli-Decoder. Mit
server.compression.brotli.enabled(Defaultfalse) komprimiert Kibana Antworten über das Pluginbrok. Kibana registriert es nur mitcompress, die Optiondecompressbleibt aus. - Ausgehend schon: axios 1.20.0, node-fetch 2.7.0 und undici 7.30.1 entpacken Brotli-Antworten automatisch. Das betrifft vor allem Connectors (Webhook, Slack, Jira, ServiceNow usw.). Ihre Ziele sind per Default nicht eingeschränkt (
xpack.actions.allowedHosts: ["*"]). - Das Image (RHEL 9.8) enthält
libbrotli1.0.9-9.el9_7, gezogen überfreetype. Gefixt ist1.0.9-10.el9_8.1(RHSA-2026:90495). Kibana nutzt diese Bibliothek nicht, Scanner melden sie trotzdem. - Für Reporting bringt Kibana ein Headless-Chromium mit (151.0.7922.77 in 9.4.8). Es hat eine eigene Brotli-Kopie und ist seit Version 148 gefixt (siehe Grafana Image Renderer).
docker run --rm --entrypoint sh docker.elastic.co/kibana/kibana:9.4.8 -c '/usr/share/kibana/node/default/bin/node -v; rpm -q libbrotli'
Gefixt ist erst Node 24.22.1.
Was tun:
- Das Patch-Release mit Node 24.22.1 einspielen, sobald es erscheint.
- Bis dahin
xpack.actions.allowedHostsauf die tatsächlich genutzten Ziele setzen. - Ausgehenden Traffic von Kibana per Egress-Regel oder Proxy auf bekannte Ziele beschränken (siehe Übergangslösung am Proxy).
[update 4] Stand 02.11.: Ein Patch-Release mit Node 24.22.1 gibt es weiter nicht. Die neuesten Releases sind weiter 9.5.5, 9.4.8 und 8.19.23 vom 06.10.
Logstash
- Logstash läuft auf JRuby und der JVM (mitgeliefertes JDK 21). Die Inputs
http,beatsundtcpnutzen Netty 4.1.138 ohne brotli4j. Netty entpacktbrdamit nicht (siehe Netty). - Weitere Brotli-Klassen stecken nur als Java-Code in Bibliotheken: die geshadete Netty-Kopie in
march_hare(RabbitMQ), Apache HttpClient 5 inlogstash-filter-elastic_integrationund commons-compress inlogstash-integration-kafka. Keine davon bringt nativen Code mit, und brotli4j liegt nirgends im Image. - Die HTTP-Plugins (
http-Output,http-Filter,http_poller) nutzen manticore auf Apache HttpClient 4.5.13. Der kennt nur gzip und deflate. - Das Gem
bindatahat eine Brotli-Transformation, die das Gembrotlinachladen würde. Dieses Gem bringt eine eigene C-Kopie vondecode.cmit, ist im Image aber nicht installiert. Wer es für eigene Ruby-Filter nachinstalliert, braucht mindestens 0.9.1 (siehe Weitere Projekte). - Das Image basiert auf RHEL 9.8 und enthält kein
libbrotli. Das mitgelieferte JDK bringt ein eigeneslibfreetypeohne Brotli mit.
# kein Treffer: kein brotli4j und kein brotli-Gem
docker run --rm --entrypoint sh docker.elastic.co/logstash/logstash:9.4.8 -c 'cd /usr/share/logstash; find vendor -iname "*brotli4j*"; ls vendor/bundle/jruby/*/gems | grep -i "^brotli"'
Was tun: Nichts wegen dieser Lücke.
Fluent Bit
Ein Advisory zu CVE-2026-111497 habe ich bis 28.10. nicht gefunden. Fluent Bit ist nach meiner Einschätzung nicht betroffen. Geprüft habe ich das Image fluent/fluent-bit:5.0 (5.0.10, distroless auf Debian 13).
- Fluent Bit ist in C geschrieben. Das Binary enthält keinen eigenen Brotli-Code.
- Es linkt
libcurl, undlibcurlhängt anlibbrotlidec. Im Image liegtlibbrotli11.1.0-2+b7, also die verwundbare Version. Gefixt ist1.1.0-2+deb13u1(DSA-6582-1). - libcurl ruft im Quellcode von Fluent Bit nur die mitgelieferte librdkafka auf (
rdhttp.c, etwa für OAuth-Token).CURLOPT_ACCEPT_ENCODINGsetzt Fluent Bit nirgends, libcurl entpackt damit kein Brotli (siehe libbrotli im Base-Image).
# Das Image hat keine Shell, deshalb die Paketdatei herauskopieren
cid=$(docker create fluent/fluent-bit:5.0)
docker cp $cid:/var/lib/dpkg/status.d/libbrotli1 - | tar -xO | grep ^Version
docker rm $cid
Was tun: Kein Notfall-Patch nötig. Das Image aktualisieren, sobald es libbrotli1 1.1.0-2+deb13u1 enthält. Ob 5.0.11 und 5.1.5 das schon tun, habe ich nicht geprüft.
[update 4] Geprüft am 02.11.: Auch fluent/fluent-bit:5.0 (5.0.11) und fluent/fluent-bit:5.1 (5.1.5) enthalten noch libbrotli1 1.1.0-2+b7. Ein neueres Release gibt es nicht.
Apache Kafka
Die CVE-Liste von Apache Kafka nennt CVE-2026-111497 bis 28.10. nicht (siehe Kafka-CVE-Übersicht). Kafka ist nach meiner Einschätzung in 2.x, 3.x und 4.x nicht betroffen. Geprüft habe ich die Images apache/kafka 4.4.0 und 3.9.2, das Release-Tarball 2.8.2 sowie confluentinc/cp-kafka 7.9.2 (Kafka 3.9) und 5.4.10 (Kafka 2.4).
Für alle Linien gilt:
- Das Kafka-Protokoll komprimiert Batches nur mit gzip, snappy, lz4 und zstd. Brotli gibt es dort nicht. Die nativen Bibliotheken
snappy-java,zstd-jniundlz4-javaenthalten keinen Brotli-Code. - brotli4j liegt in keiner Version und keinem Image auf dem Classpath, auch nicht geshadet.
- Die REST-API von Kafka Connect und MirrorMaker läuft auf Jetty. Jetty 9.4 und 12.0 kennen nur gzip (siehe Jetty). Das Modul
jetty-compression-brotliaus Jetty 12.1 bringt Kafka nicht mit. - Im laufenden Broker (KRaft,
apache/kafka4.4.0 und 3.9.2) zeigt/proc/1/mapskeine Brotli-Bibliothek.
Je Linie:
| Linie | Geprüft | HTTP/Netzwerk-Bibliotheken | Brotli im Image |
|---|---|---|---|
| 4.x | apache/kafka 4.4.0 (Alpine 3.24, JDK 25) | Jetty 12.0.39, kein Netty mehr (ZooKeeper ist entfernt) | brotli-libs 1.2.0-r1, verwundbar |
| 3.x | apache/kafka 3.9.2 (Alpine 3.23, JDK 21) | Jetty 9.4.57, Netty 4.1.125 (ZooKeeper) | brotli-libs 1.2.0-r0, verwundbar |
| 3.x | cp-kafka 7.9.2 (RHEL 8.10, JDK 17) | Jetty 9.4.57, Netty 4.1.119 | brotli 1.0.6-3.el8, verwundbar |
| 2.x | Tarball 2.8.2 | Jetty 9.4.48, Netty 4.1.73 (ZooKeeper) | kein Image |
| 2.x | cp-kafka 5.4.10 (Debian 8, JDK 8) | Jetty 9.4.48, Netty 4.1.79 | kein libbrotli |
- Netty steckt in 2.x und 3.x nur für ZooKeeper im Image.
netty-codecenthält die KlasseBrotliDecoder, entpackt ohne brotli4j aber nichts (siehe Netty). - In den Alpine-Images von
apache/kafkaziehenfreetypeundfontconfig(fürttf-dejavu) die Bibliothek mit, in 3.9.2 zusätzlichgnutlsübergnupg-dirmngr.curlist nicht installiert. Gefixt ist laut Alpine-secdb erstbrotli-libs1.2.1-r0, in 3.23 und 3.24. Das Image von 4.4.0 (Stand 22.10.) hat es noch nicht. Kafka nutzt die Bibliothek nicht, Scanner melden sie trotzdem. - In
cp-kafka7.9.2 ziehtlibcurldie Bibliothek mit. Die Startskripte unter/etc/confluent/dockerrufencurlnicht auf. Gefixt ist1.0.6-5.el8_10(RHSA-2026:90501). - 2.x bekommt seit Jahren keine Updates mehr. Das ist ein eigenes Problem, unabhängig von dieser Lücke.
Connect-Plugins von Drittanbietern (HTTP-Sinks, Cloud-Connectoren) bringen eigene Abhängigkeiten mit und müssen einzeln geprüft werden:
# kein Treffer: kein brotli4j; Plugin-Verzeichnis aus plugin.path einsetzen
docker run --rm --entrypoint sh apache/kafka:4.4.0 -c 'find /opt/kafka -iname "*brotli4j*"; apk info -v | grep -i brotli'
Was tun: Kein Notfall-Patch nötig. Images neu bauen, sobald sie das gefixte OS-Paket enthalten. Wer nicht auf ein neues offizielles Image warten will, hebt das Paket selbst:
FROM apache/kafka:4.4.0
USER root
RUN apk upgrade --no-cache brotli-libs
USER appuser
Getestet mit 4.4.0 und 3.9.2: Danach liegt brotli-libs 1.2.1-r0 im Image.
[update 4] Stand 02.11.: Das offizielle Image apache/kafka:4.4.0 ist nicht neu gebaut und enthält weiter brotli-libs 1.2.0-r1.
Apache Hadoop
Die CVE-Liste von Apache Hadoop nennt CVE-2026-111497 bis 02.11. nicht (siehe Hadoop-CVE-Übersicht). Hadoop ist nach meiner Einschätzung in 2.x und 3.x nicht betroffen. Geprüft habe ich die Images apache/hadoop 3.4.2, 3.3.6 und 2.10 (Hadoop 2.10.2).
Für alle Linien gilt:
- Hadoop hat keinen Brotli-Codec. Eingebaut sind gzip/deflate, bzip2, lz4, snappy und zstd. Die nativen Bibliotheken (
libhadoop,libhdfs,libhdfspp,libnativetask) undzstd-jnienthalten keinen Brotli-Decoder. - brotli4j liegt in keiner Version und keinem Image auf dem Classpath, auch nicht geshadet. Das gilt auch für das AWS-SDK-Bundle von
hadoop-awsund die geshadeten Client-JARs (hadoop-client-runtime,hadoop-client-minicluster). - Netty steckt mehrfach im Image: direkt (HDFS, gRPC), geshadet im AWS-SDK-Bundle und in
hadoop-client-miniclustersowie alshbase-shaded-nettyim YARN Timeline Service. Alle Kopien enthalten die KlasseBrotliDecoder, entpacken ohne brotli4j aber nichts (siehe Netty). commons-compressenthält Brotli-Klassen, die den reinen Java-Decoderorg.brotli:decbrauchen. Der liegt nicht im Image und wäre als Java-Code ohnehin unkritisch.- Die Images basieren auf CentOS 7 und enthalten kein
libbrotli.curl7.29 ist älter als die Brotli-Unterstützung in curl (ab 7.57).
Je Linie:
| Linie | Geprüft | Netty/HTTP-Bibliotheken | Brotli im Image |
|---|---|---|---|
| 3.4 | apache/hadoop 3.4.2 (CentOS 7, JDK 8u212) | Netty 4.1.118, Jetty 9.4.57, AWS SDK v2 2.29.52 | kein libbrotli |
| 3.3 | apache/hadoop 3.3.6 (CentOS 7.6, JDK 8u212) | Netty 4.1.89, Jetty 9.4.51, AWS SDK v1 1.12.367 | kein libbrotli |
| 2.x | apache/hadoop 2.10 (2.10.2, CentOS 7.6) | Netty 4.1.50 (netty-all), AWS SDK v1 1.11.271 | kein libbrotli |
- Die Images laufen auf CentOS 7, das seit dem 30.06.2024 keine Updates mehr bekommt, und auf einem JDK 8 von 2019. Hadoop 2.x bekommt ebenfalls keine Updates mehr. Das ist ein eigenes Problem, unabhängig von dieser Lücke.
- Wer den nativen HDFS-Client (
libhdfs,libhdfspp) nutzt, braucht unabhängig davon Hadoop 3.4.2 wegen CVE-2025-27821 (siehe Hadoop-CVE-Übersicht).
Frameworks auf YARN (Spark, Tez, Flink) und zusätzliche JARs im Classpath bringen eigene Abhängigkeiten mit und müssen einzeln geprüft werden. Das Image hat kein unzip, deshalb die JARs herauskopieren:
cid=$(docker create apache/hadoop:3.4.2)
docker cp $cid:/opt/hadoop /tmp/hadoop && docker rm $cid
# kein Treffer: kein brotli4j, auch nicht geshadet
for j in $(find /tmp/hadoop -name "*.jar"); do unzip -l "$j" | grep -q aayushatharva && echo "$j"; done
docker run --rm --entrypoint sh apache/hadoop:3.4.2 -c 'rpm -qa | grep -i brotli'
Was tun: Nichts wegen dieser Lücke.
Weitere Projekte mit eigener Brotli-Kopie
Viele Projekte bringen eine eigene Kopie von decode.c mit. Ein OS-Update erreicht diese Kopien nicht. Stand 26.10. laut broccoli2shell.com:
- Gefixt mit Release: Ruby-Gem
brotli0.9.1, PHP-Extensionbrotli0.21.1, UEFITool A76, MuPDF 1.28.x (1.27.x ist weiter betroffen). - Fix gemergt, aber noch kein Release: ClickHouse (Backport auf 26.10 gemergt, Backports auf 26.9, 26.8 und 26.3 LTS offen), NanaZip, GraalJS, YDB, libjxl.
- Noch ungefixt: DuckDB (PR offen), Apache Arrow (gebündeltes Brotli 1.0.9, PR approved, aber nicht gemergt), v8-jsi, 7-Zip-zstd, p7zip, EDK II, woff2 (nur der Makefile-Build; der CMake-Build linkt die System-Bibliothek).
- [update] ClickHouse hat am 26.10. auch die Backports auf 26.9, 26.8 und 26.3 LTS gemergt. Ein Release mit dem Fix gibt es noch nicht, die neuesten Releases (26.10.2.103, 26.9.25.15, 26.8.34.13, 26.3.60.2) sind alle älter als der Fix.
- [update 2] Stand 27.10.: NanaZip hat mit 7.0.1882.0 vom 26.10. ein Release mit Fix. Apache Arrow: PR #55167 hebt das gebündelte Brotli auf 1.0.10, ist approved und wartet auf die Wheel-Builds. ClickHouse und DuckDB sind unverändert.
- [update 3] Stand 28.10.: Apache Arrow PR #55167 ist weiter nicht gemergt. Die Wheel-Builds liefen am 28.10., die verbliebenen Fehler (cp314t) sind laut Maintainer unabhängig vom Fix. ClickHouse hat noch kein Release mit dem Fix. DuckDB ist weiter ungefixt, PR #27791 ist noch ein Draft. 7-Zip-zstd hat den Fix am 27.10. auf master gemergt (PR #581), erwartet in 7-Zip ZS 26.05. Für woff2 gibt es einen Fix-Vorschlag (PR #208), EDK II verfolgt die Lücke in Issue #13378. GraalJS, YDB und libjxl haben weiter kein Release mit dem Fix.
- [update 4] Stand 02.11.: Apache Arrow hat PR #55167 am 29.10. gemergt. Der Release Candidate 26.0.1-rc1 vom 30.10. bündelt laut
versions.txtBrotli 1.2.1, das finale Release 26.0.1 steht noch aus. DuckDB: PR #27791 ist kein Draft mehr, aber noch nicht gemergt. ClickHouse hat weiter kein Release mit dem Fix (neuestes: 26.10.2.103 vom 24.10.). woff2 PR #208 und EDK II Issue #13378 sind weiter offen. broccoli2shell.com (Stand 28.10.) führt zusätzlich Varnish Enterprise 6.0.18r7 als gefixt.
Übergangslösung am Proxy
Gilt für alle Stacks, solange nicht alles gepatcht ist. Eingehend am Reverse-Proxy oder Load Balancer Requests mit br im Content-Encoding ablehnen, zum Beispiel in nginx:
if ($http_content_encoding ~* "\bbr\b") {
return 415;
}
In HAProxy per ACL im frontend (oder listen):
http-request deny deny_status 415 if { req.hdr(content-encoding) -m sub -i br }
-m sub -i br prüft case-insensitiv auf das Teilwort br; bei den üblichen Encodings (gzip, deflate, compress, identity) gibt es keine Fehltreffer. Wer ganz sauber auf das Token prüfen will, nimmt eine Regex:
http-request deny deny_status 415 if { req.hdr(content-encoding) -m reg -i (^|,)[[:space:]]*br([[:space:]]*(;|,|$)) }
Ausgehend br aus Accept-Encoding entfernen und Antworten mit Content-Encoding: br vor dem Entpacken verwerfen. Nur den Header zu ändern reicht nicht, denn ein bösartiger Server schickt Brotli trotzdem.
Apache mod_brotli entpackt kein Brotli. Nginx entpackt standardmäßig auch nicht. HAProxy kann Brotli gar nicht (nur gzip/deflate, und nur beim Komprimieren von Antworten). Alle drei sind als Proxy selbst nicht betroffen und taugen damit als Filterpunkt.
Quellen
- Aikido: Node2Shell
- Aikido: HTTP2Shell und Python-Pakete
- Strobes: HTTP2Shell
- Brandefense: Fixed Node.js Versions
- Miggo: Inside Node2Shell
- Imperva: From Brotli Data to RCE
- Qualys
- Vercel KB: Node.js Security Advisory
- Debian Security Tracker
- cvefeed.io: CVE-2026-111497
- Patch the Planet: Brotli
- Mallory: Node2Shell / HTTP2Shell Rapid Response
- broccoli2shell.com: Fix-Status weiterer Projekte
- CISA KEV Feed
- dotnet/runtime#136422: Does CVE-2026-111497 affect System.IO.Compression.Brotli?
- dotnet/runtime#136430: Managed C#-Port von Brotli 1.2.1
- dotnet/announcements#211: Advisory zu CVE-2020-8927
- dotnet/announcements#494: Microsoft Security Advisory CVE-2026-111497
- Assetnote: node2shell-scanner
- brotli4j v1.24.0 Release
- Netty 4.1: Brotli.isAvailable
- Netty 4.1: HttpContentDecompressor
- Jetty 12.1: BrotliCompression
- Maven: jetty-compression-brotli 12.1.1
- Envoy Security Advisory: Out-of-Bounds Write in Brotli Decompressor (GHSA-3wvj-j6qm-62mr)
- Istio: Announcing Istio 1.30.6
- Istio Security Bulletin ISTIO-SECURITY-2026-007 (PR)
- grafana/grafana-image-renderer#1068: libbrotli1 in v5.12.9
- grafana/grafana-image-renderer#1069: Cachebuster-Bump für libbrotli1
- grafana-image-renderer: Dockerfile
- Grafana: Dockerfile
- Grafana: go.mod
- Debian: Paket chromium (trixie)
- MySQL: extra/curl CMakeLists.txt
- Grafana Alloy: go.mod
- Grafana Tempo: go.mod
- Grafana Loki: go.mod
- OpenSearch-Dashboards#13037: Bump bundled Node.js to 22.23.4
- OpenSearch-Dashboards#13048: Backport auf 3.9
- hapijs/subtext: Decoder für Request-Bodies
- Amazon Linux: ALAS2023-2026-3334 (brotli)
- Elasticsearch: transport-netty4 build.gradle
- elastic/kibana#299985: Patch-Releases mit Node.js 24.22.1
- Kibana: http_server.ts (Registrierung von brok)
- brok: Brotli-Plugin für hapi
- Tanium: HTTP2Shell, Fix-Status von Chrome und Kibana
- manticore: HTTP-Client für JRuby
- Fluent Bit: librdkafka rdhttp.c
- Apache Kafka: CVE-Liste
- Alpine secdb: v3.24 main (brotli 1.2.1-r0)
- [update] ELLIO: Node2Shell RCE on stock Node.js builds, erster Ausnutzungsversuch
- [update] Cyber Kendra: Node2Shell Exploited in the Wild
- [update] FIRST EPSS API: CVE-2026-111497
- [update] Ubuntu: CVE-2026-111497 (USN-8956-1)
- [update] Amazon Linux Security Center: CVE-2026-111497
- [update] SUSE: CVE-2026-111497
- [update] Red Hat: CVE-2026-111497
- [update] ClickHouse#127419: Bump brotli auf 1.2.1 (inkl. Backports)
- [update 2] Oracle Linux: CVE-2026-111497
- [update 2] Oracle Linux: ELSA-2026-500513 (brotli, OL 9)
- [update 2] Tenable: Brotli2Shell FAQ
- [update 2] dotnet/runtime#136471: Update Brotli to 1.1.1
- [update 2] apache/arrow#55167: Force newer versions of Brotli
- [update 3] SecurityWeek: CISA Warns of Node2Shell Exploitation as Honeypots Log Attack Attempts
- [update 3] grafana-image-renderer v5.12.10
- [update 3] grafana/grafana-image-renderer#1072: Update golang and debian base images
- [update 3] Chromium 151: third_party/brotli/README.chromium
- [update 3] google/brotli 0ed4268: Detect and report invalid stream earlier
- [update 4] Broadcom KB 460791: CVE-2026-111497 im VMware-Portfolio
- [update 4] Broadcom KB 460732: Workaround SDDC Manager 9.1.1.x
- [update 4] Broadcom KB 460734: Workaround SDDC Manager 5.2.x, 9.0.x, 9.1.0
- [update 4] Red Hat Security Data API: CVE-2026-111497
- [update 4] apache/arrow 26.0.1-rc1: cpp/thirdparty/versions.txt
- [update 4] duckdb/duckdb#27791: Pull in upstream Brotli decoder fix
- [update 4] Apache Hadoop: CVE-Liste
- [update 4] Docker Hub: apache/hadoop