# Playbook — Behebung von CVE-2026-111497

Das Verfahren, das die Skripte umsetzen, so geschrieben, dass ein menschlicher Prüfer jeden
Schritt nachvollziehen, prüfen oder übergehen kann. Jede Phase nennt ihren Beleg: den Befehl,
dessen Ausgabe die Entscheidung rechtfertigt.

## Phase 0 — Inventar des Perimeters

Festlegen, welche Hosts im Geltungsbereich liegen, und den root-Zugang über einen Schlüssel
bestätigen.

```bash
for h in <host-alias-1> <host-alias-2>; do
  ssh "$h" 'grep PRETTY_NAME /etc/os-release; dpkg -l libbrotli1 2>/dev/null | tail -1'
done
```

Abnahme: jeder Host antwortet mit einem Betriebssystemnamen und entweder einer Paketzeile oder
nichts.

## Phase 1 — Erkennung (nur lesend)

`detect.sh` erfasst, ohne das System zu verändern:

1. Identität des Hosts und Betriebssystem.
2. Version von `libbrotli1` und ihre Einordnung in die Matrix der verwundbaren Versionen.
3. Ob ein Backport der Distribution bereits eingespielt ist (das Changelog nennt die CVE).
4. Den apt-Kandidaten aus `-security` nach `apt-get update`.
5. Laufende Konsumenten von `libbrotlidec` aus `/proc/*/maps`.
6. Die Decode-Oberfläche: libcurl, Node, Python, PHP, `ngx_brotli`, `mod_brotli`.
7. Einen Inode-Snapshot der echten `.so`-Dateien für den späteren Vergleich auf veraltete
   Bindung.

Urteil: `SAFE` (0), `VULNERABLE` (1), `NOT_INSTALLED` (3), `ERROR` (10).

Abnahme: `state.before` existiert und enthält `installed`, `candidate` und die drei Inodes.

## Phase 2 — Behebung

`remediate.sh` läuft eine strikte Abfolge ab und endet bei der ersten verletzten Invariante:

1. **Sicherung** — altes `.deb`, aktuelle `.so`, `dpkg -l`-Snapshot nach
   `/root/cve-2026-111497-fix-<timestamp>/`.
2. **Gate zur Echtheitsprüfung** — den Kandidaten herunterladen und `CVE-2026-111497` in seinem
   mitgelieferten Changelog verlangen. Ein Kandidat, der nur neuer aussieht, wird abgelehnt.
3. **Probelauf** — `apt-get install --only-upgrade --dry-run`; die erwartete Menge besteht genau
   aus den Brotli-Paketen und nichts sonst.
4. **Installation** — `libbrotli1`, zusätzlich `libbrotli-dev`, wenn es zuvor installiert war.
5. **Neustart der Konsumenten** — jede systemd-Unit, deren Prozesse `libbrotlidec` einbinden,
   aufgelöst bis zur innersten Unit unter `/system.slice/`, damit Template-Instanzen erfasst
   werden; Daemons von Panels, die als transiente Scopes gestartet wurden, werden über ihr
   eigenes Steuerwerkzeug neu gestartet.
6. **Inode-Prüfung** — kein Server-Konsument darf noch einen Inode von vor dem Patch eingebunden
   halten.

Abnahme: Exit 0 und eine Zeile `REMEDIATED:` mit der alten und der neuen Version.

## Phase 3 — Verifikation

`verify.sh` bestätigt fünf Tatsachen:

1. Die Paketversion hat sich geändert.
2. Das installierte Changelog nennt `CVE-2026-111497`.
3. Kein Serverprozess bindet einen Inode von vor dem Patch ein.
4. `systemctl --failed` ist leer.
5. Ein funktionaler Decode-Rundlauf gelingt (lokaler `br`-Endpunkt oder die `brotli`-CLI).

Abnahme: `VERIFY: PASS`, Exit 0.

## Manuelle Gegenprüfung (unabhängig von den Skripten)

```bash
dpkg -l | grep -E 'brotli'
apt-cache policy libbrotli1
zgrep -i CVE-2026-111497 /usr/share/doc/libbrotli1/changelog.Debian.gz
# no process may map the pre-patch decoder:
grep -l libbrotlidec /proc/[0-9]*/maps 2>/dev/null | wc -l
```

## Rollback

```bash
dpkg -i /root/cve-2026-111497-fix-<timestamp>/deb/libbrotli1_*.deb
# then restart every service listed in phase 2, step 5
```

Ein Rollback stellt per Definition die verwundbare Version wieder her. Er ist nur einzusetzen,
wenn das gepatchte Paket eine Abhängigkeit bricht, und die Entscheidung ist zu protokollieren.

## Vorübergehende Mitigation, wenn kein Backport existiert

Anfragen mit `Content-Encoding: br` (einschließlich zusammengesetzter Werte wie `gzip, br`) am
Reverse Proxy oder an der WAF zurückweisen, bevor sie die Anwendung erreichen, und mit
`415 Unsupported Media Type` antworten. Das ist ein Behelfsmittel, kein Ersatz für die
Aktualisierung: es schützt nur eingehende Körper und lässt jeden ausgehenden libcurl-Abruf
exponiert.

## Abschlusskriterien

- `detect.sh` liefert bei einem erneuten Lauf 0, oder `verify.sh` liefert nach der Behebung
  `VERIFY: PASS`.
- Das Sicherungsverzeichnis ist vorhanden und nicht leer.
- Die gehosteten Websites antworten mit ihrem Status von vor der Änderung.
- Die zurückgestellten Desktop-Konsumenten sind im Bericht erfasst, mit der Erwartung, dass sie
  die gepatchte Bibliothek bei der nächsten Anmeldung oder beim nächsten Neustart laden.
