Gegenbuch: nur vertrauenswuerdige Signaturen, fail-closed ohne Remote (R176)

R176-01 (HIGH): Das Signatur-Gate akzeptierte %G? = G ODER U. Bei
SSH-Signaturen bedeutet U woertlich "gute Signatur, aber kein passender
Principal" - der Schluessel steht also NICHT in allowed_signers. Damit
passierte jeder selbst erzeugte Schluessel das Gate und der einzige
In-System-Vertrauensanker war wirkungslos. End-to-end reproduziert: Gegenbuch
mit fremdem Schluessel re-signiert und force-gepusht -> "OK", exit 0.
Vorbedingung war nur Remote-Schreibrecht, kein Host-Zugriff.
Fix: nur G an beiden Stellen, dazu optionales Pinnen des erwarteten
Signierschluessels ueber NOTARY_SIGNER_FINGERPRINT (%GF).

R176-02 (MEDIUM): War der Remote unerreichbar, fiel der Ablauf still auf HEAD
zurueck und die "nie gepusht"-Pruefung wurde uebersprungen - ausgerechnet unter
der Bedingung, die einen Push-Fehlschlag verursacht. --check meldete waehrend
eines Ausfalls gruenes Licht auf nicht notarisiertem Zustand. Fix: fail-closed
mit Code 3, ebenso ohne konfigurierten Remote (Testlauf nur mit
NOTARY_ALLOW_LOCAL=true).

Nebenbei: git-eigene Fehlermeldungen standen vor der eigenen Erklaerung, stderr
wird jetzt abgefangen und gezielt weitergereicht.

Verifiziert mit zwei SSH-Schluesseln gegen echten Remote: Angriff mit fremdem
Key + Force-Push -> Alarm exit 2 (vorher OK); Remote unerreichbar -> exit 3;
kein Remote -> exit 3; falscher Fingerabdruck-Pin -> Alarm; saubere Historie
ohne Fehlalarm. Rueckgabecodes in der README dokumentiert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-21 20:26:55 +02:00
co-authored by Claude Opus 5
parent 375d4ae1e2
commit 5952fb1894
3 changed files with 131 additions and 8 deletions
+31
View File
@@ -97,6 +97,37 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
## ✅ Erledigt
- [x] **🔑 Gegenbuch: nur wirklich vertrauenswuerdige Signaturen, fail-closed ohne Remote (Pentest R176)** (2026-08-18)
- **R176-01 (HIGH)** Mein Signatur-Gate akzeptierte `%G?` = `G` **oder**
`U`. Bei SSH-Signaturen bedeutet `U` woertlich „gute Signatur, aber kein
passender Principal“ also: der Schluessel steht **nicht** in
`allowed_signers`. Damit passierte **jeder selbst erzeugte Schluessel** das
Gate, und der einzige In-System-Vertrauensanker war wirkungslos. Der
Pentester hat es end-to-end gefahren: Gegenbuch mit fremdem Schluessel
re-signiert und force-gepusht → „OK, Signaturen gültig“, exit 0.
Vorbedingung war nur Remote-Schreibrecht, kein Host-Zugriff.
Fix: **nur `G`** an beiden Stellen. Zusaetzlich optionales Pinnen des
erwarteten Signierschluessels ueber `NOTARY_SIGNER_FINGERPRINT` (`%GF`).
- **R176-02 (MEDIUM)** War der Remote unerreichbar, fiel der Ablauf still
auf `HEAD` zurueck und die „nie gepusht“-Pruefung wurde uebersprungen
ausgerechnet unter der Bedingung, die einen Push-Fehlschlag verursacht.
`--check` meldete waehrend eines Remote-Ausfalls gruenes Licht auf nicht
notarisiertem Zustand. Fix: **fail-closed**, Abbruch mit Code 3 statt dem
lokalen Stand zu glauben; ebenso, wenn gar kein Remote konfiguriert ist
(bewusster Testlauf nur mit `NOTARY_ALLOW_LOCAL=true`).
- Nebenbei: git-eigene Fehlermeldungen standen VOR der eigenen Erklaerung
stderr wird jetzt abgefangen und gezielt weitergereicht.
- Verifiziert mit zwei SSH-Schluesseln (keyA vertrauenswuerdig, keyB nicht)
gegen echten Remote: Angriff mit keyB + Force-Push → **Alarm, exit 2**
(vorher „OK“); Remote unerreichbar → **exit 3**; kein Remote → exit 3;
falscher Fingerabdruck-Pin → Alarm; **saubere Historie: drei Laeufe und
Pruefmodus ohne Fehlalarm**. Alle Testartefakte geloescht, Port frei.
- Seine Antwort auf Frage (a) uebernommen: der Vergleich Arbeitsdatei ↔
signierter Baum ist nicht umgehbar; `.trim()` auf beiden Seiten schluckt
nur Kosmetik. Notiert als Restrisiko: internes CRLF koennte bei
`core.autocrlf` auf dem Notar-Host einen Fehlalarm ausloesen
Verfuegbarkeit, kein Integritaetsloch.
- [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