# Bedrohungsmodell — CVE-2026-111497 (Out-of-Bounds-Schreibzugriff im Brotli-Decoder)

Dieses Dokument legt fest, was das Werkzeug als exponiert betrachtet, was es ausdrücklich nicht
abdeckt und warum die Klassifikation dort gezogen ist, wo sie liegt. Es ist die Referenz für die
Auslegung jedes Urteils, das die Skripte zurückgeben.

## 1. Die Schwachstelle

| Eigenschaft | Wert |
|---|---|
| Kennung | CVE-2026-111497 |
| Komponente | Google Brotli, Decoder (`c/dec/decode.c`) |
| Schwäche | CWE-787, Out-of-Bounds-Schreibzugriff |
| Verwundbare Upstream-Versionen | 1.0.3 … 1.0.9, 1.1.0, 1.2.0 |
| Korrigierte Upstream-Versionen | 1.0.10, 1.1.1, 1.2.1 (21. Oktober 2026) |
| Angriffsvektor | präparierter Brotli-Stream, der dem Decoder übergeben wird |
| Authentifizierung erforderlich | nein |
| Auswirkung | Prozessabbruch, Speicherkorruption, in bestimmten Konfigurationen Remote-Code-Execution |
| Schweregrad | CVSS 4.0 9.2 gemäß Veröffentlichung des Projekts; 8.5 auf der CVSS-3.x-Skala in den Trackern der Distributionen |

Der defekte Pfad ist die Zustandsmaschine des Decoders an einem Blockübergang: ein fehlerhafter
Stream treibt die internen Zähler über die vorgesehene Grenze hinaus, und der Decoder schreibt
über den reservierten Ausgabepuffer hinaus, statt den ungültigen Stream früh zu melden. Die
Korrektur im Upstream erkennt und meldet den ungültigen Stream vor dem Schreibzugriff.

## 2. Was exponiert ist und was nicht

Die Unterscheidung, die die meisten Urteile entscheidet:

- Ein **Encoder** (nginx `ngx_brotli`, `mod_brotli`, Pipelines für statische Assets) komprimiert
  Daten, die der Server selbst erzeugt hat. Er parst nie vom Angreifer kontrolliertes Brotli. Er
  ist nicht die Angriffsfläche, obwohl er dasselbe Paket bindet.
- Ein **Decoder** nimmt Daten von außen an und parst sie. Das ist die Angriffsfläche.

| Pfad | Exponiert, wenn | Anmerkungen |
|---|---|---|
| HTTP-Anfragekörper | die Anwendung oder ein Proxy `Content-Encoding: br` dekomprimiert | der wirkungsvollste Vektor, wo er existiert |
| Ausgehender HTTP-Client | libcurl mit leerem `CURLOPT_ENCODING`, Node `fetch`, Python `httpx`/`requests` mit Brotli | ein bösartiger oder kompromittierter Dritter antwortet mit `br` |
| Antwortkette über einen Proxy | Envoy/Istio-HTTP-Decompressor aktiviert | der Proxy wird zum Decoder |
| Datei-Upload oder -Import | die Anwendung Brotli-Archive oder -Streams dekomprimiert | in Prüfungen oft übersehen |
| Mitgelieferte Laufzeitumgebung | Node.js, Bun, .NET-Request-Dekompression | die Korrektur kommt mit der Laufzeitumgebung, nicht mit `libbrotli1` |

## 3. Warum libcurl die realen Flotten dominiert

Auf drei Produktionshosts gemessen: der erreichbare Vektor waren nie „Anfragen an den Webserver“,
denn nginx und Apache nutzten Brotli nur zur Kompression, und keiner von beiden dekodierte
Anfragekörper. Der dominierende Pfad war **ausgehendes HTTP über libcurl**, erreicht aus
PHP-Anwendungscode.

`CURLOPT_ENCODING` mit einer leeren Zeichenkette weist libcurl an, jede Kodierung anzukündigen und
zu akzeptieren, die es unterstützt, einschließlich `br`. Dieses eine Argument erscheint in:

- WordPress `wp-includes/Requests/src/Transport/Curl.php`;
- WordPress SimplePie `File.php`;
- Guzzle-Handler-Factories, die in Plugins mitgeliefert werden;
- direktem `wp_remote_*`-Verkehr, RSS-Abrufen und Aufrufen von Anbieter-APIs.

Auf einem Host zählte das Inventar 164 PHP-Dateien mit `CURLOPT_ENCODING` oder
`CURLOPT_ACCEPT_ENCODING`. Diese Zahl ist das eigentliche Maß der Exposition auf einem Shared-
Hosting-System — nicht das bloße Vorhandensein des Pakets.

## 4. Angreifermodell

| Position des Angreifers | Fähigkeit | Konsequenz |
|---|---|---|
| Remote, nicht authentifiziert | sendet einen präparierten Brotli-Körper oder liefert eine präparierte `br`-Antwort aus | Absturz, Speicherkorruption, mögliche Codeausführung im dekodierenden Prozess |
| Drittanbieter von Inhalten | kontrolliert einen Endpunkt, den der Server abruft | erreicht den Decode-Pfad von libcurl, ohne den Perimeter zu berühren |
| Lokal ohne Privilegien | liefert eine Datei, die die Anwendung dekomprimiert | derselbe Decoder, geringere Auswirkung |

Das Werkzeug setzt voraus, dass der Angreifer die Bytes wählen kann und den Prozess nicht wählen
kann: das Ziel der Prüfung ist sicherzustellen, dass kein erreichbarer Decoder in einem
verwundbaren Prozess verbleibt.

## 5. Erkennungsstrategie

Das Vorhandensein eines Pakets ist keine Exposition. Der Detektor erfasst daher vier unabhängige
Tatsachen und klassifiziert erst, wenn alle vier bekannt sind:

1. die installierte Version, mit entferntem Epoch und entfernter Distributionsrevision, sodass die
   Upstream-Nummer bleibt;
2. ob das mitgelieferte Changelog die CVE bereits nennt (Backport der Distribution eingespielt);
3. ob der apt-Kandidat neuer ist als die installierte Version (eine unterstützte Korrektur
   existiert);
4. welche laufenden Prozesse `libbrotlidec` einbinden und über welche Laufzeitumgebung.

Ein Host ist nur dann `VULNERABLE`, wenn die Upstream-Version im verwundbaren Bereich liegt
**und** kein Backport vorhanden ist. Ein Host ist `SAFE`, wenn eine der beiden Bedingungen nicht
zutrifft — einschließlich des Falls einer Distributionsrevision, die die verwundbar aussehende
Upstream-Nummer behält und die Korrektur dennoch enthält.

## 6. Außerhalb des Geltungsbereichs

| Bereich | Grund |
|---|---|
| Statisch gebundene Kopien | für `dpkg` unsichtbar; erforderte eine binäre Prüfung jeder Datei |
| Container-Images | verlangen eine Prüfung auf Registry-Seite, nicht eine Untersuchung auf dem Host |
| Envoy, Istio, .NET, Bun, Deno | eigene Lebenszyklen der Behebung; dokumentiert, nicht automatisiert |
| Windows- und macOS-Hosts | das Werkzeug ist ausschließlich bash und apt |
| Mitigationen auf Anwendungsebene | das Blockieren von `Content-Encoding: br` ist ein Behelfsmittel, das der Betreiber anwendet, keine Korrektur |

## 7. Restrisiko nach der Behebung

1. Desktop- und Infrastrukturprozesse halten die alte Bibliothek eingebunden, bis zur nächsten
   Anmeldung oder zum nächsten Neustart. Sie sind kein Decode-Pfad eines Servers; der Detektor
   meldet sie als `deferred`.
2. Ein Prozess, der aus einem **nach** der Behebung, aber vor dem Austausch der Bibliothek
   installierten Paket gestartet wurde, würde die gepatchte Bibliothek erben — die Reihenfolge
   innerhalb von `remediate.sh` verhindert den umgekehrten Fall.
3. Anwendungscode, der sein eigenes Brotli mitbringt (mitgelieferter Quellcode, statischer Bau),
   ist von der Paketaktualisierung nicht betroffen und muss getrennt neu gebaut werden.

Das Verfahren steht in [PLAYBOOK.de.md](PLAYBOOK.de.md), und was diese drei Tatsachen auf realen
Hosts ergaben, in [FIELD-REPORT.de.md](FIELD-REPORT.de.md).
