Brotli-Lücke CVE-2026-111497: Notfallpatch für .NET erklärt

Am Sonntag, dem 25. Oktober 2026, hat Microsoft außerplanmäßige Sicherheitsupdates für .NET 8, 9, 10 und den dritten Release Candidate von .NET 11 veröffentlicht. Anlass ist CVE-2026-111497, eine Schwachstelle im Brotli-Decoder, die unter den Namen Node2Shell, HTTP2Shell und Broccoli2Shell seit einer Woche durch die Fachpresse geht. Ein Angreifer kann mit einem präparierten, Brotli-komprimierten Datenstrom den Speicher des entpackenden Prozesses beschädigen, Speicherinhalte auslesen, den Prozess abstürzen lassen oder im schlimmsten Fall eigenen Code ausführen.

Das klingt nach einem Fall für „sofort alles patchen”. Ganz so einfach ist es nicht, und das ist der eigentliche Grund für diesen Artikel. Die Lücke steckt in einer Bibliothek von Google, die in Dutzenden Produkten mitgeliefert wird, und ob eine konkrete .NET-Anwendung angreifbar ist, hängt von ihrer Konfiguration ab. Ich gehe durch, was die Lücke ist, warum sie erst jetzt Schlagzeilen macht, obwohl der Fix seit Februar existiert, welche .NET-Versionen Sie brauchen und was Sie tun können, wenn Sie nicht sofort updaten können.

Was CVE-2026-111497 technisch ist

Brotli ist ein verlustfreies Kompressionsverfahren von Google, das vor allem im Web eingesetzt wird: Browser und Server tauschen HTML, CSS und JavaScript mit Content-Encoding: br aus. Die Referenzimplementierung in C ist die Grundlage für fast alle Brotli-Decoder in Umlauf, egal ob in Node.js, Python, Bun, Envoy oder eben in .NET.

Der Fehler sitzt in der Funktion DecodeBlockTypeAndLength() in c/dec/decode.c. Sie verarbeitet die Stellen, an denen ein Brotli-Strom den Blocktyp wechselt. In den betroffenen Versionen gibt die Funktion nur „wahr” oder „falsch” zurück, und „falsch” kann zweierlei heißen: der Strom ist kaputt, oder es fehlen noch Eingabedaten. Der Aufrufer kann das nicht unterscheiden, und im schnellen Decodierpfad wird der Rückgabewert ohnehin ignoriert. Ein präparierter Strom erklärt einen einzigen Blocktyp, lässt dessen Länge auf null laufen und erzwingt so einen Wechsel, der nicht gelingen kann. Der Decoder arbeitet dann mit veraltetem Zustand weiter und schreibt über einen kleinen internen Puffer hinaus. Das Node.js-Advisory vom 21. Oktober beschreibt es so: Ein ungültiger Blockwechsel wurde als vorübergehender Bedarf an mehr Eingabe gemeldet statt als dauerhafter Formatfehler, und der Streaming-Decoder hängte weiter Bytes an einen acht Byte großen internen Puffer an.

Der Fix im Brotli-Repository lässt die Funktion einen echten Fehlercode zurückgeben, BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH mit dem Wert -17, und bricht auf beiden Pfaden ab. Betroffen sind laut CVE-Record die Brotli-Versionen 1.0.3 bis 1.2.0; behoben ist das Problem in 1.0.10, 1.1.1 und 1.2.1, je nach Entwicklungszweig.

Gefunden haben die Lücke Khai Tran und Sylvie Mayer von OpenAI Codex Security. Dass sich daraus mehr als ein Absturz machen lässt, hat das Red Team von Imperva gezeigt: Ron Masas beschreibt in seiner Analyse vom 22. Oktober, wie sein Proof of Concept auf dem offiziellen Node.js-24.22.0-Image für Linux arm64 mitgelieferten Code ausführte, sowohl über eine komprimierte HTTP-Antwort, die fetch() entpackt, als auch über einen Brotli-komprimierten Request-Body in Express 5 mit body-parser. Die Ausführung klappte nicht bei jedem Versuch, aber sie klappte. Auf 24.22.1 wurde dieselbe Eingabe abgewiesen.

Warum die Lücke seit Februar bekannt war

Das ist der Teil, der mich an der Geschichte ärgert. Der CVE-Record von Google nennt als datePublic den 27. Februar 2026. Die Ursache wurde damals im Brotli-Quellcode korrigiert. Nur hat das niemand als Sicherheitskorrektur behandelt, und deshalb gab es bis Oktober kein Release, das den Fix enthielt. So beschreibt es Aikido Security in seiner Zeitleiste, und Upwind kommt in seiner Analyse zum gleichen Befund.

Acht Monate lang lag ein Fix für eine Lücke, die Remote Code Execution ermöglicht, offen in einem öffentlichen Repository, ohne dass irgendjemand ein Paket gebaut hätte. Wer wollte, konnte den Commit lesen. Erst als Node.js am 21. Oktober ein Advisory samt Fixes veröffentlichte, kam die Kette in Gang: Am 22. Oktober der CVE-Record und die Python-Pakete, am 23. die Bibliothek selbst in Version 1.2.1 sowie Bun, Envoy und Istio, am 24. die Java-Bindings und Amazon Linux, am 25. Microsoft mit .NET, am 26. Debian und Alpine. Ubuntu, SUSE und die regulären Red-Hat-Repositories hatten zum Stand 26. Oktober noch keinen Fix.

Zeitleiste von CVE-2026-111497: Fix im Brotli-Quellcode am 27. Februar 2026 ohne Release, dann ab dem 21. Oktober innerhalb einer Woche Fixes für Node.js, Python, libbrotli, .NET und Linux-Distributionen

Die Grafik zeigt, warum sich der Name so oft geändert hat. „Node2Shell” war der erste Name, weil Node.js zuerst patchte. „HTTP2Shell” kam am 23. Oktober auf, als klar wurde, dass jede Software betroffen ist, die Brotli über HTTP entpackt; mit dem Protokoll HTTP/2 hat die Lücke nichts zu tun. „Broccoli2Shell” ist der Name, den Wiz Research verwendet. Gemeint ist immer dieselbe CVE.

Fairerweise: Microsoft hat vergleichsweise schnell reagiert. Vier Tage nach dem Node.js-Advisory einen Out-of-Band-Patch für vier Produktlinien zu liefern, an einem Sonntag, ist nicht selbstverständlich. Dass der Patch nötig war, liegt nicht an Microsoft, sondern daran, dass .NET wie fast jedes andere Produkt seine eigene Kopie des Brotli-Decoders mitbringt.

Welche .NET-Anwendungen angreifbar sind

Hier wird es für die Praxis wichtig. Das Microsoft-Advisory sagt ausdrücklich: Eine Anwendung ist nicht angreifbar, nur weil ein betroffenes .NET-Paket installiert ist. Angreifbar ist sie, wenn sie von Angreifern kontrollierte Brotli-Daten über einen von drei Wegen entpackt:

  1. ASP.NET Core Request Decompression ist aktiviert und akzeptiert br. Dann entpackt der Server eingehende Request-Bodies, bevor irgendeine Authentifizierung greift.
  2. HttpClientHandler.AutomaticDecompression oder SocketsHttpHandler.AutomaticDecompression enthält DecompressionMethods.Brotli oder DecompressionMethods.All. Dann entpackt der Client Antworten fremder Server. Ein bösartiger Server kann also eine Anwendung angreifen, die ihn nur abfragt, etwa einen Webhook-Empfänger, einen Link-Preview-Dienst oder einen Importer, der URLs lädt.
  3. Die Anwendung ruft BrotliStream oder BrotliDecoder aus System.IO.Compression direkt auf nicht vertrauenswürdige Daten auf, zum Beispiel beim Entpacken hochgeladener Dateien.

Keiner dieser Wege ist in einer frischen .NET- oder ASP.NET-Core-Installation aktiv. Request Decompression muss man explizit registrieren, automatische Antwort-Dekompression explizit konfigurieren. Das .NET Framework ist nicht betroffen. Diese Einschränkung erklärt auch, warum Microsoft die Lücke anders bewertet als der CVE-Record.

CVSS 8.1 oder 9.2, hoch oder kritisch?

Im CVE-Record, den Google als vergebende Stelle gepflegt hat, steht ein CVSS-4.0-Wert von 9.2, Einstufung „Critical”. Microsoft bewertet dieselbe Lücke in seinem Advisory nach CVSS 3.1 mit 8.1 und Schweregrad „High”, mit dem Vektor CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C. Der Unterschied liegt in der Angriffskomplexität: Microsoft setzt sie auf „hoch” (AC:H), was zu der Einschränkung passt, dass die Anwendung erst eine der genannten Konfigurationen haben muss. BleepingComputer schreibt in seiner Meldung vom 26. Oktober von einer kritischen Lücke und bezieht sich damit auf den CVE-Record, nicht auf die Microsoft-Einstufung.

Beide Zahlen sind richtig, sie beantworten nur verschiedene Fragen. 9.2 beschreibt die Bibliothek: Wer sie auf fremde Daten loslässt, hat ein kritisches Problem. 8.1 beschreibt .NET als Produkt, in dem diese Bibliothek standardmäßig nicht auf fremde Daten losgelassen wird. Für Ihre Anwendung zählt, welche der beiden Beschreibungen zutrifft.

Die Updates: Versionen und was Microsoft gleich mitrepariert

Die fehlerbereinigten Versionen laut .NET-Blog und Advisory:

.NET-LinieRuntimeSDK
.NET 88.0.338.0.133 oder 8.0.427
.NET 99.0.229.0.123 oder 9.0.320
.NET 1010.0.1410.0.114 oder 10.0.403
.NET 1111.0.0-rc.3.26522.148 (RC3)11.0.100-rc.3.26522.148

Wer .NET 11 RC2 einsetzt, muss auf RC3 wechseln; RC2 bekommt den Fix nicht. .NET 7 ist laut Aikido ebenfalls betroffen, aber seit Mai 2024 ohne Support und bekommt deshalb nichts mehr. Für .NET 8 und 9 ist das Update übrigens eines der letzten: Beide Linien laufen laut Microsofts Support-Tabelle am 10. November 2026 aus, also in zwei Wochen. .NET 10 als LTS-Version ist bis zum 14. November 2028 versorgt.

Im selben Paket behebt Microsoft CVE-2026-114148, falsche Besitzrechte in den Linux-Tarballs von .NET, über die ein lokaler Angreifer Dateien ändern und Rechte ausweiten könnte. Bei .NET 10 und 11 betrifft das nur Source-Build-Tarballs, bei .NET 8 und 9 auch die ASP.NET-Core-Tarballs für normale Nutzer. Und dann ist da noch ein Satz im Blogbeitrag, der mir aufgefallen ist: Microsoft veröffentlicht die Advisories für CVE-2026-70197 (Speicherfehler in SocketAsyncEventArgs) und CVE-2026-102870 (Blazor-WebAssembly-Debugger) neu, weil das Update vom 13. Oktober diese beiden Lücken nicht vollständig geschlossen hat. Erst der jetzige Patch liefert die kompletten Fixes.

Das passt in ein Muster, das ich auf diesem Blog öfter beschreibe: Ein Patch-Tuesday-Update, das zwei Sicherheitslücken nur halb schließt, ist kein Einzelfall mehr. Ich rate seit einiger Zeit dazu, Windows-Updates einen Monat versetzt einzuspielen, weil die Qualität der Erstauslieferung das nicht mehr hergibt. Für diesen .NET-Patch gilt die Empfehlung allerdings nicht, und zwar aus zwei Gründen: Es ist ein Runtime-Update, kein kumulatives Windows-Update mit Nebenwirkungen auf das ganze System, und es gibt bereits funktionierende Exploits.

Ausnutzung: Proof of Concept ja, Angriffe in freier Wildbahn nein

Nach Angaben von BleepingComputer sind Proof-of-Concept-Exploits auf GitHub veröffentlicht. Imperva hat seinen Exploit in einem Video vorgeführt und beschrieben, dass er auf einem unveränderten Node.js-Build funktioniert. Berichte über Angriffe in freier Wildbahn gab es zum Stand 26. Oktober nicht; Upwind merkt an, dass die Lücke auch nicht im KEV-Katalog der CISA steht.

Zwei Dinge sollten Sie trotzdem einpreisen. Erstens: Wiz Research gibt an, dass laut eigenen Daten 91 Prozent der von Wiz beobachteten Cloud-Umgebungen Ressourcen mit dieser Lücke enthalten. Die Zahl stammt von einem Anbieter, der Scanner verkauft, und ich kann sie nicht nachprüfen, aber die Größenordnung ist plausibel, wenn man bedenkt, wie viele Container irgendeine Node.js- oder Python-Komponente mitbringen. Zweitens: Um die Lücke hat sich bereits ein Rattenschwanz an Trittbrettfahrern gebildet. Brandefense warnt in seiner Übersicht vor angeblichen Prüf-Tools, Exploit-Verkäufen und einem Krypto-Token namens „$HTTP2SHELL”, der mit der Lücke nichts zu tun hat. Wer jetzt nach Scannern sucht, sollte nur Quellen vertrauen, die er auch sonst nutzt.

Was Sie jetzt prüfen sollten

Wenn Sie .NET-Anwendungen betreiben oder entwickeln, ist die Reihenfolge aus meiner Sicht diese.

Zuerst klären, ob Brotli überhaupt entpackt wird. Suchen Sie im Code nach AddRequestDecompression, AutomaticDecompression, DecompressionMethods.Brotli, DecompressionMethods.All, BrotliStream und BrotliDecoder. Finden Sie nichts, ist die Anwendung nach Microsofts Beschreibung nicht angreifbar, und das Update kann den normalen Weg gehen. Finden Sie etwas, ist die Anwendung dran.

Dann prüfen, welche Runtime tatsächlich läuft. dotnet --list-runtimes zeigt die installierten Shared Runtimes auf einem Host. Framework-abhängige Anwendungen nutzen nach Installation der neuen Runtime und einem Neustart automatisch die fehlerbereinigte Version; auf Windows kommt das Runtime-Update laut Microsofts Support-Seite auch über Microsoft Update. Selbständige Anwendungen (self-contained) bringen ihre eigene Runtime mit und müssen mit dem aktualisierten SDK neu gebaut und ausgerollt werden. Dasselbe gilt für Container-Images und für NativeAOT-Anwendungen, bei denen der Decoder in die ausführbare Datei eingebunden ist. Ein Runtime-Update auf dem Host hilft diesen Anwendungen nicht. Das ist der Punkt, an dem Inventarlisten lügen: Ein Server kann 8.0.33 melden und trotzdem fünf Dienste mit eingebautem altem Decoder betreiben.

Drittens, falls das Update nicht sofort geht: Brotli abschalten, aber nur dort, wo es schon aktiv ist. Microsoft warnt im Advisory ausdrücklich davor, AddRequestDecompression oder AutomaticDecompression neu einzuführen, nur um Brotli dann auszuschließen, weil das Aktivieren der Dekompression eigene Denial-of-Service-Risiken mitbringt. Wer Request Decompression bereits nutzt, entfernt den br-Provider:

builder.Services.AddRequestDecompression(options =>
{
    options.DecompressionProviders.Remove("br");
});

Wer den HttpClient bereits mit automatischer Dekompression betreibt, beschränkt die Flags auf gzip und deflate:

var handler = new HttpClientHandler
{
    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};

Alternativ lässt sich Content-Encoding: br am Reverse Proxy oder an der Firewall abweisen. Das deckt aber nur eingehende Anfragen ab. Für den Fall, dass Ihre Anwendung fremde Server abfragt, hilft das nicht, und das Entfernen von br aus dem Accept-Encoding-Header hilft ebenfalls nicht, weil ein bösartiger Server trotzdem Brotli senden kann und viele Clients den Decoder nach dem Antwort-Header auswählen.

Und viertens der Blick über .NET hinaus. Die gleiche Lücke steckt in Node.js, Python-Paketen, Bun, curl-Builds mit Brotli, Envoy, Istio und in der libbrotli vieler Linux-Distributionen. Wer einen Reverse Proxy, eine Monitoring-Lösung, ein Ticketsystem oder eine Fachanwendung von Drittherstellern betreibt, hat vermutlich mehrere Kopien des Decoders im Haus, ohne es zu wissen. Zumindest eine Entwarnung gibt es: Apaches mod_brotli komprimiert nur und entpackt nicht, läuft also nicht in den anfälligen Code.

Fazit

CVE-2026-111497 ist eine Bibliotheks-Lücke, die erst durch das Node.js-Advisory vom 21. Oktober zu einem Ereignis wurde, obwohl der Fix seit Februar im Quellcode lag. Für .NET hat Microsoft am 25. Oktober geliefert, mit den Versionen 8.0.33, 9.0.22, 10.0.14 und 11 RC3, und dabei zwei halb geschlossene Lücken vom Oktober-Patchday gleich mit nachgebessert. Angreifbar sind nur Anwendungen, die Brotli-Daten aus fremder Hand entpacken, dann aber ohne Authentifizierung und in beide Richtungen.

Mein Vorschlag für heute Abend: Greppen Sie Ihre .NET-Projekte nach den sechs Bezeichnern aus dem Praxisabschnitt. Was Treffer hat, wird diese Woche neu gebaut und ausgerollt. Was keine hat, bekommt das Update im normalen Rhythmus. Und wer noch auf .NET 8 oder 9 sitzt, hat mit dem 10. November ohnehin einen Termin, der nicht wegen Brotli näher rückt.


Quellen:

Nach oben scrollen