Node2Shell: die Brotli-Lücke in Node.js, wer betroffen ist und wie du sie schließt
Node2Shell ist der Name, den Forscher CVE-2026-111497 gegeben haben, einer Lücke im Brotli-Decoder, der in Node.js steckt. Am 21. Oktober 2026 hat das Node.js-Projekt sie in 22.23.4, 24.22.1 und 26.12.1 behoben. Eine App, die Brotli-Daten entpackt, die jemand anderes liefern kann, etwa einen komprimierten Request-Body oder eine Antwort von einem fremden Server, kann abstürzen, Speicher preisgeben oder Code eines Angreifers ausführen. Die Korrektur steckt in Node.js selbst, also hilft `npm update` nicht: Die Laufzeitumgebung muss überall aktualisiert werden, wo sie läuft.
Was Node2Shell ist
Brotli ist ein Kompressionsformat, das Webserver und Browser neben gzip verwenden. Node.js bringt in `node:zlib` einen Brotli-Decoder mit. Das Node.js-Advisory beschreibt den Fehler: Ein ungültiger Blockwechsel in einem komprimierten Datenstrom wurde als vorübergehender Bedarf an mehr Eingabe behandelt statt als Formatfehler, also hängte der Decoder weiter Bytes an einen acht Byte großen internen Puffer an und schrieb über dessen Ende hinaus. So eine Speicherbeschädigung kann den Prozess abstürzen lassen, Speicherinhalte preisgeben oder einem Angreifer erlauben, Code auszuführen.
Node.js stuft sie als hoch ein und sagt, sie erlaube die Ausführung von Fremdcode. Gemeldet hat sie OpenAI Codex Security. Forscher von Imperva haben sie danach als Codeausführung ohne Anmeldung nachgestellt, und Proof-of-Concept-Code ist öffentlich – behandle also jeden ungepatchten Node.js-Dienst, der Daten von außen verarbeitet, als Ziel.
Bist du betroffen?
Ein Node.js-Prozess ist betroffen, wenn er oder eine genutzte Bibliothek Brotli-Daten entpackt, die ein Angreifer kontrolliert. Imperva hat zwei häufige Wege getestet.
**Eingehende Anfragen.** Express 5 und body-parser 2 entpacken Request-Bodys mit `Content-Encoding: br`, weil die Option `inflate` von body-parser standardmäßig an ist. Eine App mit `app.use(express.json())` ist also über eine einzige präparierte Anfrage erreichbar, noch vor jeder Anmeldung.
**Ausgehende Anfragen.** Das eingebaute `fetch()` von Node fordert Brotli-Antworten von selbst an und entpackt sie. Jeder Server, den dein Code aufruft und den ein Angreifer kontrolliert oder übernommen hat, erreicht den Decoder: Webhooks, die du zurückrufst, Link-Vorschauen, Scraper, KI-Agenten, die Seiten abrufen, die ein Nutzer ihnen gibt, Health-Checks anderer Websites.
Code, der die Brotli-Funktionen aus `node:zlib` direkt auf Daten von außen anwendet, ist genauso betroffen. Firewalls vor deiner App sehen nur den ersten Weg: Was dein Code von anderswo abruft, können sie nicht prüfen.
Welche Versionen die Lücke schließen
Jede unterstützte Node.js-Linie hat ein Release mit der Korrektur (siehe Tabelle). Dasselbe Release behebt neun weitere Lücken, darunter drei als hoch eingestufte Fehler bei TLS-Zertifikaten und DNS, also lohnt es sich auch dann, wenn deine App nie mit Brotli arbeitet.
Node.js 20 und älter bekommen keine Korrektur: Ihr Lebensende ist erreicht, und laut Node.js-Projekt sind Versionen nach dem Lebensende bei jedem Sicherheitsrelease immer betroffen. Bun, das einen eigenen Brotli-Decoder mitbringt, hat dieselbe Lücke in 1.4.4 behoben.
Wo Node.js überall steckt
Das Update muss jede Kopie von Node erreichen, die deinen Code ausführt, und meistens gibt es mehr als eine.
**Container-Images.** Ein Dockerfile, das eine exakte Version festlegt, etwa `node:24.22.0`, bleibt angreifbar, egal wie oft du neu baust: Setze die Version auf 24.22.1 oder neuer. Basis-Images mit eigenem Node (zum Beispiel Images für Browser-Tests) frieren die Version ein, die beim Bauen aktuell war, also aktualisiere Node auch darin.
**Server und CI.** Node, das über nvm, einen Paketmanager oder eine CI-Setup-Aktion installiert wurde, wird dort aktualisiert und der Dienst danach neu gestartet.
**Hosting-Plattformen.** Vercel hat am 21. Oktober für jedes Projekt Firewall-Regeln gegen den eingehenden Weg ausgerollt und verwaltet die Patch-Versionen seiner Node.js-Laufzeiten 22.x und 24.x selbst, diese Projekte brauchen also keine Versionsänderung. Projekte, die noch auf Node.js 20 laufen, müssen auf 22.x oder 24.x wechseln und neu deployen. Vercel weist auch darauf hin, dass seine Firewall keine Antworten abdeckt, die deine Functions von anderen Servern abrufen. Bei anderen Hostern prüfst du deren eigene Mitteilung, welche Node-Version deine Functions ausführt.
**Mit KI gebaute Apps.** Wenn ein KI-App-Builder oder ein Coding-Agent den Servercode deiner App geschrieben hat, ist die Frage dieselbe: Welche Laufzeit führt ihn aus, und in welcher Version? Unter Monitoring für KI-erstellte Apps steht, worauf du achten solltest, sobald sie live ist.
So prüfst du es
Führe `node --version` auf Laptops, CI-Runnern und Servern aus und `docker run --rm <image> node --version` für jedes Container-Image. In einem laufenden Dienst kannst du `process.version` beim Start ins Log schreiben. Alles unter dem korrigierten Release seiner Linie, oder auf Node.js 20 und älter, muss aktualisiert werden.
Wenn du heute nicht aktualisieren kannst
Das Update ist die Lösung. Bis es überall ausgerollt ist, kannst du den eingehenden Weg einengen: Lehne Anfragen mit `Content-Encoding: br` an deinem Proxy oder deiner Firewall ab, oder setze `inflate: false` bei body-parser und `express.json()` – das lehnt jeden komprimierten Request-Body ab (prüfe vorher, dass keiner deiner Clients welche schickt).
Für den ausgehenden Weg gibt es keine schützende Einstellung, weil ein bösartiger Server eine Brotli-Antwort schicken kann, egal was dein Code anfordert. Ruf von ungepatchten Diensten aus keine nicht vertrauenswürdigen URLs ab, bis sie aktualisiert sind.
Wie Relvato hilft
Relvato kann die Node.js-Version einer Website nicht von außen auslesen und schickt keine angriffsähnlichen Anfragen, um sie herauszufinden, deshalb meldet es Node2Shell nicht direkt.
Was es tut: Der Exposure-Scan meldet einen `X-Powered-By: Express`-Header, der jedem Scanner deinen Stack verrät (`app.disable("x-powered-by")` entfernt ihn). Und ein Node-Update ist eine Änderung wie jede andere: Mit Deploy-Prüfungen über GitHub führt Relvato deine Monitore nach dem Deploy erneut aus, damit du weißt, dass Anmeldung, Checkout und deine wichtigsten Seiten auf der neuen Laufzeit noch funktionieren.
Relvato läuft auch auf Node.js. Seine Monitore rufen Seiten von den Websites ab, die sie überwachen, deshalb haben wir sie in der Woche der Korrektur auf Node 24.22.1 umgestellt.
Laufzeiten mit der Node2Shell-Korrektur
| Laufzeit | Behoben in | Hinweis |
|---|---|---|
| Node.js 26 | 26.12.1 | Aktuelle Release-Linie |
| Node.js 24 | 24.22.1 | LTS |
| Node.js 22 | 22.23.4 | LTS |
| Node.js 20 und älter | Keine Korrektur | Lebensende: auf 22 oder 24 aktualisieren |
| Bun | 1.4.4 | Bringt einen eigenen Brotli-Decoder mit |
Fragen und Antworten
Behebt npm update Node2Shell?
Nein. Die Lücke steckt in Node.js selbst, nicht in einem Paket, also ändert ein Update der Abhängigkeiten nichts daran. Aktualisiere die Node.js-Laufzeit überall, wo dein Code läuft, auf 22.23.4, 24.22.1 oder 26.12.1 oder neuer, und starte danach neu oder deploye neu.
Ich nutze kein Express. Bin ich sicher?
Nicht unbedingt. Das eingebaute fetch() von Node entpackt Brotli-Antworten standardmäßig, also ist Code, der von Servern abruft, die du nicht kontrollierst, unabhängig vom Framework betroffen. Aktualisiere Node trotzdem.
Meine App läuft auf Vercel. Muss ich etwas tun?
Auf Node.js 22.x oder 24.x verwaltet Vercel die Patch-Version und hat Firewall-Regeln gegen präparierte Request-Bodys, eine Versionsänderung ist also nicht nötig. Auf Node.js 20 wechselst du auf 22.x oder 24.x und deployst neu. Vercels Firewall deckt keine Antworten ab, die deine Functions von anderen Servern abrufen.
Ich nutze Node.js 20 oder 18. Was jetzt?
Sie bekommen keine Korrektur: Beide haben ihr Lebensende erreicht. Aktualisiere auf Node.js 22 oder 24, teste und deploye neu.
Schützt mich eine Web Application Firewall?
Nur gegen präparierte eingehende Anfragen. Die Antworten, die dein Code von anderen Servern abruft, sieht sie nicht, und das ist der andere Weg hinein. Regeln verschaffen Zeit, die Lösung ist das Update.
Quellen
- Node.js — Wednesday, October 21, 2026 Security Releases
- Imperva — Node2Shell: From Brotli Data to Remote Code Execution
- Vercel — Node.js security advisory: Brotli decoder RCE (CVE-2026-111497)
- Aikido — Node2Shell: Node.js Brotli vulnerability allows remote code execution and the fix
- body-parser — the inflate option (expressjs/body-parser)
- Bun — brotli: reject invalid block switch (CVE-2026-111497), oven-sh/bun #46351