← Übersicht

Node2Shell / Python2Shell / HTTP2Shell (CVE-2026-111497)

Stand: 02.11.2026

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:

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:

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.

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)

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:

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:

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":

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:

Gateways nicht vergessen: dieselben Checks gegen die Ingress-/Egress-Gateway-Pods laufen lassen.

Was tun

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:

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.

  1. 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.
  2. Docker-Images neu bauen (FROM node:... mit gepatchtem Tag) und neu deployen. Danach im laufenden Container node -v prüfen. CI-Runner nicht vergessen. Die nodejs-Pakete von Debian (bookworm bis sid) führt der Debian-Tracker am 26.10. noch als verwundbar.
  3. Bun auf 1.4.4 aktualisieren und mit Bun kompilierte Executables neu bauen.
  4. 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
  1. Brotli auf 1.2.1 und brotlicffi auf 1.2.1.0 aktualisieren.
  2. Images und Wheels neu bauen, Prozesse neu starten.
  3. 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.

.NETBetroffenGepatchte RuntimeGepatchtes SDK
8.0< 8.0.338.0.338.0.133, 8.0.427
9.0< 9.0.229.0.229.0.123, 9.0.320
10.0< 10.0.1410.0.1410.0.114, 10.0.403
11.0 Preview< 11.0.0-rc.3.26522.14811.0.0-rc.3.26522.14811.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:

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:

  1. Runtime bzw. SDK auf die gepatchte Version heben, Docker-Images neu bauen und Anwendungen neu starten.
  2. Self-contained Apps mit der neuen Runtime neu bauen und neu deployen, weil sie die Runtime mitbringen.
  3. NativeAOT-Apps: SDK und explizite Referenzen auf Microsoft.DotNet.ILCompiler und die Runtime-Packs aktualisieren, dann neu publishen. Ein Update der Shared Runtime ersetzt den Decoder nicht, der schon ins Executable gelinkt ist.
  4. Direkte Paketreferenzen auf die gepatchten Versionen heben.

Bis zum Update:

  1. In der Request Decompression den Brotli-Provider entfernen: services.AddRequestDecompression(o => o.DecompressionProviders.Remove("br"));
  2. Bei HttpClient nur DecompressionMethods.GZip | DecompressionMethods.Deflate setzen statt All.
  3. Eingehend br am 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

Grafana Image Renderer

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

  1. 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
  1. Den Renderer nur intern erreichbar machen, sodass nur Grafana ihn aufruft, und das Auth-Token (rendering.renderer_token in Grafana) setzen.
  2. Keine fremden Inhalte in Dashboards einbinden, die gerendert werden, solange der Chromium-Status unklar ist.
  3. 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.:

ImageBrotli im BinarycgoBasislibbrotli im Image
Alloygrafana/alloy 1.21.2andybalholm/brotli v1.2.4an, linkt nur libcUbuntu 24.04nein
Tempografana/tempo:latest (3.0.0)andybalholm/brotli v1.1.1ausdistrolessnein
Lokigrafana/loki 3.7.9andybalholm/brotli v1.2.6ausdistrolessnein
# 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.

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

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:

DashboardsMitgeliefertes NodeStatus
2.19.x (auch 2.19.6)18.19.0Node 18 bekommt keinen Patch
3.0 bis 3.420.18.3Node 20 bekommt keinen Patch
3.5 und 3.622.22.0verwundbar
3.722.22.3verwundbar
3.8 und 3.922.23.0Bump 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:

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:

  1. Auf das erste 3.9.x-Release mit Node 22.23.4 aktualisieren, sobald es erscheint.
  2. 2.19 und 3.0 bis 3.4 bekommen über ihre Node-Version keinen Fix. Upgrade auf die gepatchte 3.x-Linie planen.
  3. Für 3.5 bis 3.9 lässt sich bis dahin ein gepatchtes Node einsetzen. bin/use_node nimmt OSD_NODE_HOME vor 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.

  1. Ausgehenden Traffic von Dashboards per Egress-Regel oder Proxy auf bekannte Ziele beschränken. Ein Proxy, der Antworten mit Content-Encoding: br verwirft, 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

Was tun: Nichts wegen dieser Lücke.

Kibana

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:

  1. Das Patch-Release mit Node 24.22.1 einspielen, sobald es erscheint.
  2. Bis dahin xpack.actions.allowedHosts auf die tatsächlich genutzten Ziele setzen.
  3. 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

# 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).

# 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:

Je Linie:

LinieGeprüftHTTP/Netzwerk-BibliothekenBrotli im Image
4.xapache/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.xapache/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.xcp-kafka 7.9.2 (RHEL 8.10, JDK 17)Jetty 9.4.57, Netty 4.1.119brotli 1.0.6-3.el8, verwundbar
2.xTarball 2.8.2Jetty 9.4.48, Netty 4.1.73 (ZooKeeper)kein Image
2.xcp-kafka 5.4.10 (Debian 8, JDK 8)Jetty 9.4.48, Netty 4.1.79kein libbrotli

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:

Je Linie:

LinieGeprüftNetty/HTTP-BibliothekenBrotli im Image
3.4apache/hadoop 3.4.2 (CentOS 7, JDK 8u212)Netty 4.1.118, Jetty 9.4.57, AWS SDK v2 2.29.52kein libbrotli
3.3apache/hadoop 3.3.6 (CentOS 7.6, JDK 8u212)Netty 4.1.89, Jetty 9.4.51, AWS SDK v1 1.12.367kein libbrotli
2.xapache/hadoop 2.10 (2.10.2, CentOS 7.6)Netty 4.1.50 (netty-all), AWS SDK v1 1.11.271kein libbrotli

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:

Ü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