Gegenbuch: verifizierender Leser statt Absichtserklaerung (Pentest R175)

R175-01 (HIGH): Die erste Fassung signierte zwar, prueft aber nie. Sie las ihre
Wahrheit per readFileSync aus der lokalen Arbeitsdatei, nirgends gab es ein
git verify-commit - das -S war write-only ohne Konsument. Live reproduziert:
DB-Tail abgeschnitten und die lokale Ledger-Zeile angepasst -> "OK, Checkpoint
beglaubigt", exit 0, kein Alarm.

Fix: Wahrheitsquelle ist der signierte Commit-Baum (bevorzugt der Remote-Kopf);
jeder Commit mit Gegenbuch-Aenderung muss eine gueltige Signatur tragen; weicht
die Arbeitsdatei vom signierten Stand ab, wird abgebrochen; lokale, nie
gepushte Commits gelten nicht als beglaubigt; die Signatur des frisch
erzeugten Commits wird gegengeprueft. Dazu ein Pruefmodus --check fuer
Auditoren.

R175-02 (MEDIUM): /checkpoint fuhr je Aufruf ein volles verifyIntegrity (O(n),
0,85 s bei 16k Zeilen) - authentifizierte DoS-Verstaerkung. Gebraucht wurde nur
die Siegel-Wurzel. Jetzt Kopf-Hash aus der Kopfzeile, Wurzel aus dem juengsten
gueltigen Marker, sealLeafCount statt des teuren Status.

R175-03: writeFileSync lief vor dem Commit, eine verwaiste Zeile wurde vom
Folgelauf zementiert. Jetzt Ruecknahme bei Fehlschlag, und NOTARY_SIGN=false
verlangt zusaetzlich NOTARY_INSECURE_ACK.

Verifiziert mit echtem SSH-Signaturschluessel: stilles Waschen -> Alarm;
erfundene Zeile -> Alarm; unsignierter Commit -> Alarm; Commit-Fehlschlag ->
zurueckgerollt; Reflex-Schalter verweigert; Pruefmodus haengt nichts an.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 16:13:54 +02:00
co-authored by Claude Opus 5
parent f3ded9afbc
commit 375d4ae1e2
4 changed files with 293 additions and 76 deletions
+38
View File
@@ -97,6 +97,44 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
## ✅ Erledigt
- [x] **🔏 Gegenbuch: verifizierender Leser statt Absichtserklaerung (Pentest R175)** (2026-08-18)
- **R175-01 (HIGH)** Der Kernsatz des Pentesters: „Append-only allein
reicht nicht, es braucht einen verifizierenden Leser.“ Meine erste Fassung
signierte zwar, **prüfte aber nie**: Sie las ihre Wahrheit per
`readFileSync` aus der lokalen **Arbeitsdatei**, nirgends im Repo gab es
ein `git verify-commit`. Das `-S` war write-only ohne Konsument. Live
reproduziert: DB-Tail abgeschnitten UND die lokale Ledger-Zeile angepasst →
„OK, Checkpoint beglaubigt“, exit 0, kein Alarm. Der gekuerzte Zustand
wurde zur neuen Wahrheit.
Fix: Wahrheitsquelle ist der **signierte Commit-Baum** (bevorzugt der
Remote-Kopf); jeder Commit mit Gegenbuch-Aenderung muss eine gueltige
Signatur tragen; weicht die Arbeitsdatei vom signierten Stand ab, wird
abgebrochen; lokale, nie gepushte Commits gelten nicht als beglaubigt;
die Signatur des frisch erzeugten Commits wird gegengeprueft.
Dazu ein **Pruefmodus** `--check` fuer Auditoren (alle Kontrollen, kein
Schreibrecht noetig).
- **R175-02 (MEDIUM)** `/checkpoint` fuhr je Aufruf ein volles
`verifyIntegrity()` (O(n), gemessen 0,85 s bei 16k Zeilen) authentifizierte
DoS-Verstaerkung. Gebraucht wurde davon nur die Siegel-Wurzel. Jetzt:
Kopf-Hash direkt aus der Kopfzeile, Wurzel aus dem juengsten gueltigen
Marker (eine Abfrage + Signaturpruefung), plus `sealLeafCount` statt des
teuren Status.
- **R175-03 (LOW→MED)** `writeFileSync` lief vor dem Commit: schlug der
signierte Commit fehl, blieb eine verwaiste Zeile liegen, die der
Folgelauf absorbierte und zementierte. Jetzt Ruecknahme bei Fehlschlag
(`git checkout`), und `NOTARY_SIGN=false` verlangt zusaetzlich
`NOTARY_INSECURE_ACK=…` der Reflex „Cron hakt, Signatur abschalten“
soll nicht ausreichen.
- Verifiziert mit **echtem SSH-Signaturschluessel** gegen eine CRM-Attrappe:
stilles Waschen (DB gekuerzt + lokale Datei gebogen) → Alarm statt „OK“;
frei erfundene, nie committete Zeile → Alarm; unsignierter Commit in der
Historie → Alarm; Commit-Fehlschlag → Datei zurueckgerollt, keine
Geisterzeile; `NOTARY_SIGN=false` ohne Bestaetigung → verweigert;
Pruefmodus meldet sauber ohne anzuhaengen. Alle Testartefakte geloescht.
- Seine Bestaetigungen: Key-Trennung im Deploy haelt (`printenv` im
Container zeigt keinen Notar-Schluessel); `audit:read` kann am
Checkpoint keine falschen Werte injizieren.
- [x] **⚖️ Gegenbuch: externe Notarisierung der Audit-Kette** (2026-08-18)
- Abschluss der Anker-Kette. Alle bisherigen Schutzebenen liegen in
derselben Datenbank, die sie absichern sollen der Pentest hat das ueber