Brotli-RCE CVE-2026-111497: 25 von 37 Node-Runtimes unter der Fix-Version
Am 21. Oktober hat das Node.js-Projekt drei Wartungsversionen veröffentlicht, die unter anderem einen Schreibfehler im gebündelten Brotli-Decoder beheben. Der Decoder stammt von Google und steckt in vielen weiteren Produkten. Am Vormittag des 26. Oktobers lasen wir 37 Node-Runtimes auf vier unserer Hosts aus: 12 laufen auf einer gepatchten Version, 25 darunter. Dazu kommt eine Falle bei der Frage, woran man den Patchstand überhaupt erkennt.
CVE-2026-111497 in Kürze: Ein präparierter Brotli-Datenstrom lässt den Decoder über das Ende eines acht Byte großen internen Puffers hinaus schreiben. Das kann den Prozess abstürzen lassen, Speicher preisgeben oder Code ausführen. Betroffen ist der Decoder von Google in den Versionen 1.0.3 bis 1.2.0 und damit jede Software, die ihn mit fremden Daten füttert: Node.js, die PyPI-Pakete Brotli und brotlicffi, .NET und weitere. Gefixt ist er seit dem 21. Oktober 2026 in den Versionen 1.0.10, 1.1.1 und 1.2.1.
Stand 5. November: die Lücke wird ausgenutzt
Dieser Beitrag erschien am 26. Oktober. Bei der Nachprüfung am 5. November mussten drei Aussagen korrigiert werden.
- Ausnutzung. Die erste Fassung schrieb, die CISA-Liste enthalte die CVE nicht. Das stimmte am Abruftag. Seit dem 27. Oktober 2026 steht sie dort, die Frist für US-Bundesbehörden endet am 10. November. Am 5. November haben wir im CISA-Katalog (Katalogstand 2026.11.04, 1768 Einträge) nachgelesen. Ob Ransomware-Gruppen die Lücke nutzen, vermerkt die CISA mit „Unknown".
- Exploit-Reichweite. Wir hatten geschrieben, der öffentliche Proof of Concept führe auf Standardbauten nur zum Absturz. So meldete es eine Community-Übersicht. ELLIO schreibt dagegen, es habe mit diesem Exploit auf unveränderten x86-64-Builds eine Shell erhalten, bei vier Zielen, und am 26. Oktober Angriffsverkehr mit demselben Exploit beobachtet. Wer patcht, sollte deshalb von Codeausführung ausgehen.
- NVD. Der Eintrag stand am 26. Oktober auf „Awaiting Analysis", heute auf „Analyzed" und trägt zusätzlich einen CVSS-3.1-Wert von 9.8 des NIST.
Unsere eigenen Hosts haben wir am 27. Oktober nachgezogen: Eigene Images und Host-Node laufen seit dem Abend auf 24.22.1, ein Drift-Check über 49 Hosts meldete keinen Befund. Das stammt aus unserer internen Betriebsnotiz und ist nicht öffentlich belegbar. Die Messwerte unten sind der Stand vom 26. Oktober vor diesen Änderungen.
Was die Lücke kann und was sie braucht
Der Decoder wechselt beim Entpacken zwischen Blocktypen. Bis zum Fix meldete die zuständige Funktion einen ungültigen Blockwechsel als „brauche mehr Eingabe" statt als dauerhaften Formatfehler. Der Streaming-Decoder hängte deshalb weitere Angreifer-Bytes an einen acht Byte großen Puffer an und schrieb über dessen Grenze. So beschreibt es das Node.js-Advisory. Node.js übernimmt den Upstream-Fix als Cherry-pick in die Versionen 22.23.4, 24.22.1 und 26.12.1. Das Projekt weist außerdem darauf hin, dass End-of-Life-Versionen bei einem Security-Release immer betroffen sind. Laut broccoli2shell.com gibt es für diese Zweige keinen Fix, sie müssen auf 22, 24 oder 26 wechseln.
Entscheidend ist, wo der Decoder ungeprüfte Daten anfasst. Die Übersicht auf broccoli2shell.com, eine unabhängig gepflegte Community-Seite, nennt drei Wege. Das eingebaute fetch() von Node dekodiert Antworten mit Content-Encoding: br von selbst. Express 5.0.0 bis 5.3.0 und body-parser 2.0.0 bis 2.3.0 dekodieren Brotli-Anfragekörper. Direktes zlib.brotliDecompress() verarbeitet Archive oder Nachrichten in Warteschlangen. Ein nackter node:http-Server dekodiert eingehende Körper nicht von selbst, das bestätigt auch Imperva. Imperva führte Code auf dem offiziellen Image Node.js 24.22.0 (Linux arm64) aus, über eine abgeholte Antwort und über einen Express-Anfragekörper, mit mehreren Anläufen. Dieselben Eingaben lehnte 24.22.1 ab. Dass Imperva den Exploit nicht veröffentlicht hat, steht auf broccoli2shell.com; bei Imperva selbst steht dazu nichts.
Laut broccoli2shell.com genügt es bei Python, dass das Paket Brotli oder brotlicffi installiert ist. urllib3, requests und aiohttp verhandeln Accept-Encoding: br und rufen den Decoder, ohne dass eigener Code ihn nennt. OpenSourceMalware zeigte per Sanitizer-Test, dass Brotli 1.2.0 einen präparierten Strom von etwa 23 MB durchlässt und 1.2.1 ihn mit dem Formatfehler -17 verwirft. Einen Exploit für Python hat dort niemand versucht. Die offiziellen Node.js-Builds und Images bündeln eine eigene Kopie, dort hilft die libbrotli1 des Systems nicht. Laut ELLIO und dem Debian-Tracker ("nodejs uses system provided brotli library") linken Distributionspakete von Node dagegen die Systembibliothek, bei ihnen entscheidet deren Paketstand.
Die Produktliste reicht laut broccoli2shell.com von Bun und Envoy über Ruby-Bindings bis zu .NET. Istio kommt dort nicht vor; die Istio-Versionen nennt Wiz. Für .NET bestätigt der Eintrag im Microsoft Security Response Center eine Rechteausweitung über das Netz, Schweregrad Critical, veröffentlicht am 25. Oktober. Eingebaute Kopien warteten laut der Seite am 28. Oktober noch auf ihre Maintainer, darunter DuckDB, Apache Arrow, p7zip und die UEFI-Firmware EDK II. Ob sie inzwischen gepatcht sind, haben wir nicht nachgesehen.
Wer wie bewertet
Der Schweregrad hängt am Zähler. Die Werte unten sind am 5. November bei den Quellen abgelesen, Einheit ist der jeweilige CVSS-Wert.
| Quelle | Bewertung | Skala |
|---|---|---|
| Node.js-Advisory | high | Projekt-eigene Einstufung |
| GitHub Advisory Database | Critical, 9.2 | CVSS 4.0 |
| NVD, eingereicht von Google | Critical, 9.2 | CVSS 4.0 |
| NVD, NIST | Critical, 9.8 | CVSS 3.1 |
| Microsoft (.NET) | Critical, Basiswert 8.1 | Rechteausweitung |
Der Vektor mit 9.2 nimmt vollen Verlust von Vertraulichkeit, Integrität und Verfügbarkeit am angegriffenen System an, ohne Folgen für weitere Systeme. Das Node-Projekt bleibt mit „high" darunter. Wiz meldet aus eigener Telemetrie, dass 91 Prozent der Cloud-Umgebungen betroffene Ressourcen hätten. Das ist die Zahl einer Sicherheitsfirma mit eigenem Interesse am Befund, die wir nicht nachprüfen können.
Zeitplan der Offenlegung
Alle Daten stammen aus den verlinkten Quellen, nichts davon haben wir selbst gemessen.
| Datum | Ereignis | Quelle |
|---|---|---|
| 21.10. | Node.js 22.23.4, 24.22.1, 26.12.1 und Brotli 1.0.10, 1.1.1, 1.2.1 erscheinen | Node.js, Google |
| 22.10. | NVD-Eintrag, GitHub-Advisory, PyPI-Paket Brotli 1.2.1, Imperva-Bericht, öffentlicher Proof of Concept | NVD, GitHub, OpenSourceMalware, Imperva, broccoli2shell.com (Proof of Concept) |
| 23.10. | brotlicffi 1.2.1.0 auf PyPI | OpenSourceMalware |
| 25.10. | .NET-Updates und MSRC-Eintrag | Microsoft |
| 26.10. | ELLIO meldet Angriffsverkehr mit dem öffentlichen Exploit | ELLIO |
| 27.10. | Aufnahme in den CISA-Katalog, Frist 10.11. | CISA |
Was bei uns gemessen ist
Abgefragt wurde am 26. Oktober zwischen 07:24 und 07:31 UTC per SSH: jeder Node-Host und jeder Node-Container auf vier Hosts (.181.3, .200.11, .180.2 und .180.1). Einheit ist die Node-Release-Nummer aus node --version, verglichen mit den Fix-Versionen 22.23.4, 24.22.1 und 26.12.1.
| Messstelle (eigene Messung, 26.10.2026) | Läufe | Node-Stand | Status |
|---|---|---|---|
| Blog-Host .181.3, Wirt plus drei Next.js-Container | 4 | 24.22.1 | auf der Fix-Version |
| Umami-Container auf .181.3 | 1 | 22.23.4 | auf der Fix-Version |
| tl-gui und zahlungen-ui auf .200.11 | 2 | 24.22.1, 22.23.4 | auf der Fix-Version |
| agent-watchdog, rbs-kompensator, rbs-kalkulator-mcp, zahlungen-ui (.180.2) | 4 | 22.23.4 | auf der Fix-Version |
| dsh-eval auf .180.1 | 1 | 22.23.4 | auf der Fix-Version |
| slg-tickets, slg-pruefungen, senn-frachttarife, mcp-erp-lookup (.200.11) | 4 | 24.22.0 | eine Version darunter |
| litellm-router auf .200.11 | 1 | 26.12.0 | eine Version darunter |
| Wirt .200.11 | 1 | 22.22.1 | darunter |
| open-design, mcp-open-design, librechat-api (.180.2) | 3 | 24.21.0 | darunter |
| litellm-router-Container auf .180.2 | 1 | 26.10.0 | darunter |
| 11 MCP- und KSA-Container (.180.2), darunter mcp-erp-lookup und senn-agent-mcp | 11 | 22.22.2 bis 22.23.3 | darunter |
| Wirt .180.2 | 1 | 22.22.1 | darunter |
| Crawl-Wirt .180.1 | 1 | 22.22.1 | darunter |
| senn-tech-preview und dsh-capacity-sidecar (.180.1) | 2 | 22.23.3 | darunter |
Die Läufe summieren sich auf 12 auf der Fix-Version und 25 darunter, also 37. „Darunter" sagt nur, dass die Release-Nummer unter dem Fix liegt. Wie gefährlich das ist, hängt am Pfad. LibreChat und Open Design holen Antworten von externen KI-Anbietern und Webservices und treffen damit den ausgehenden Dekodierpfad, weil jeder angesprochene Server mit Content-Encoding: br antworten darf. Die vier SLG-Container auf .200.11 sprechen intern mit OSRM, ERP und Datenbank, dort ist die Datenquelle im Normalbetrieb im Haus.
Drei Pfade waren am selben Vormittag dicht: Zammad 7.2 kennt das Ruby-Brotli-Gem nicht, auf unserem Webhost ist die PHP-Brotli-Erweiterung nicht geladen, und im LiteLLM-Container scheitert import brotli, weil das Paket fehlt. Nicht messen konnten wir die Windows-Flotte, den dc1-Host ohne Schlüssel und den Backup-Host, der SSH verweigerte.
Die Anzeige im Binary ist nicht der Patch
Auf dem Crawl-Wirt .180.1 lief am 26. Oktober v22.22.1. Das Systempaket libbrotli1 stand auf 1.2.0-3build1, ebenfalls in der betroffenen Spanne, und in unseren Paketquellen war an diesem Tag kein neueres sichtbar. Das ist ein Stand vom 26. Oktober; Distributionspakete ziehen nach, ein späterer Abruf kann anders aussehen.
Beim Patchstand führt die Versionsanzeige des Decoders in die Irre. Node.js hat den Fix als einzelnen Upstream-Commit eingespielt, die Release Notes zu Node.js 24.22.1 führen ihn als deps: brotli: cherry-pick 0ed4268a…. Die gebündelte Nummer in process.versions.brotli blieb dabei nicht verlässlich. Eine Nachmessung am 5. November ergab:
| Host (eigene Messung, 05.11.2026) | node --version | process.versions.brotli |
|---|---|---|
| Blog-Host .181.3 | v24.22.1 | 1.2.1 |
| dsh-Host .180.1 | v24.22.1 | 1.2.0 |
Dasselbe Release zeigt also zwei verschiedene Decoder-Nummern. Ein Prüfskript, das „brotli ab 1.2.1" verlangt, hält zwei gleichwertig gepatchte Binaries für verschieden gut. Warum die Nummern auseinanderlaufen, wissen wir nicht, die Quellen erklären es nicht. Wer automatisierte Scanner fährt, prüft die Release-Nummer von Node gegen das Advisory, bei Python zusätzlich pip show Brotli brotlicffi, bei Systembibliotheken den Paketstand von dpkg, rpm oder apk.
Was Firmen jetzt tun
Als Erstes der Bestand. Node-Programme laufen in Unternehmen oft, ohne dass jemand sie bestellt hat: hinter Next.js-Frontends, n8n, Node-RED, Chat-Oberflächen und Monitoring-Appliances steckt ein Node-Runtime, und die Release-Nummer entscheidet über den Stand, nicht das Installationsdatum. Dazu gehören Notebooks mit Browsern, NAS-Oberflächen und Tools mit eingebauter Kopie wie p7zip. Bei einer Lücke, die die CISA als ausgenutzt führt, gehören Dienste zuerst dran, die fremde URLs abrufen oder br-Anfragekörper annehmen.
Wirksam ist der Neubau. Ein Host-Update erreicht die Images nicht. Container brauchen eine gepatchte Basis und einen neuen Build, Python-Lockfiles aktualisierte Einträge, sonst baut der nächste Lauf die alte Version wieder ein. Wer nicht sofort wechseln kann, kann laut broccoli2shell.com Content-Encoding: br am Proxy oder Gateway abweisen und bei Python die Pakete Brotli und brotlicffi deinstallieren, dann fallen urllib3 und requests auf gzip zurück. Für ausgehende Anfragen hilft das nur begrenzt, denn ein Server darf Brotli auch ohne Aufforderung senden. Für Node hat das Projekt laut broccoli2shell.com keinen Workaround veröffentlicht.
Wer den Bestand nicht selbst inventarisieren will, kann die Bestandsaufnahme über unsere IT-Leistung für Infrastruktur und Betrieb beauftragen. Wie so ein Flottencheck über Hosts, Container und Paketstände Schritt für Schritt läuft, steht im curl-Flottencheck, dieselbe Reihenfolge steckt hinter diesem Beitrag. Die Meldung selbst mit den .NET- und Python-Fixes im Überblick fasst der Beitrag zur Brotli-Lücke in Node.js, Python und .NET zusammen; dieser Beitrag setzt dagegen auf die Messung unserer eigenen Flotte und führt den Stand der Ausnutzung nach. Weitere Lücken, bei denen wir den Bestand nachgemessen haben, sammelt der Themenkanal Security und Datenschutz, etwa der PHP-RCE-Patchtag mit derselben Neustartfalle.
Weiterführende Quellen
- Node.js-Projekt: Wednesday, October 21, 2026 Security Releases, 21.10.2026
- Node.js-Projekt: Node.js 24.22.1 (LTS), 21.10.2026
- Google: Brotli-Releases 1.0.10, 1.1.1, 1.2.1, 21.10.2026
- GitHub Advisory Database: GHSA-9v8h-qqgm-4m35, Stand 03.11.2026
- NVD: CVE-2026-111497, abgerufen 05.11.2026 per NVD-API (Status Analyzed)
- CISA: Known Exploited Vulnerabilities Catalog und Katalog als JSON, Stand 04.11.2026
- Microsoft: CVE-2026-111497 im Security Update Guide, 25.10.2026
- Imperva: Node2Shell: From Brotli Data to Remote Code Execution, 22.10.2026
- ELLIO: Node2Shell: remote code execution on stock Node.js builds, 25.10.2026, Nachtrag 26.10.2026
- OpenSourceMalware: Brotli-Auswirkung auf Python-Pakete, 23.10.2026
- Wiz: Broccoli2shell im Überblick, 25.10.2026
- Community-Übersicht: broccoli2shell.com, unabhängig gepflegt, Stand 28.10.2026
Wird die Lücke CVE-2026-111497 schon ausgenutzt?+
Ja. Die CISA hat die Lücke am 27. Oktober 2026 in den Katalog der bekannten ausgenutzten Schwachstellen aufgenommen, die Frist für US-Bundesbehörden endet am 10. November. Das Sicherheitsunternehmen ELLIO meldete schon am 26. Oktober Angriffsverkehr mit dem öffentlichen Exploit. Die erste Fassung dieses Beitrags vom 26. Oktober schrieb noch das Gegenteil, weil der Katalogeintrag erst einen Tag später kam.
Reicht ein apt upgrade auf dem Host?+
Nicht für jedes Node-Programm. Die offiziellen Node.js-Builds und Images bündeln eine eigene Kopie des Decoders, dort ändert die libbrotli1 des Systems nichts. Laut ELLIO und dem Debian-Tracker linken Distributionspakete von Node dagegen die Systembibliothek, bei ihnen zählt auch das Paket libbrotli1. In Containern läuft ein eigenes Dateisystem aus dem Image, das kein Host-Update erreicht. Der wirksame Schritt ist ein Neubau des Images auf einer gepatchten Basis, danach der Neustart des Prozesses, denn ein laufender Prozess behält den alten Decoder.
Warum zeigt mein gepatchtes Node 24.22.1 trotzdem Brotli 1.2.0 an?+
Weil das Node-Projekt den Fix als einzelnen Upstream-Commit übernommen hat (laut Release Notes zu 24.22.1 ein Cherry-pick) und laut ELLIO die gebündelte Versionsnummer nicht anhob. Bei einer Messung am 5. November zeigte dasselbe Release 24.22.1 auf zwei unserer Hosts einmal 1.2.0 und einmal 1.2.1. Maßgeblich ist die Release-Nummer von Node gegen die Advisory-Liste, die Decoder-Anzeige taugt als Nachweis nicht.
senn-tech