fix(format-v3): harden system binding against replay and bypass attacks (F-01, F-02, F-03)
- F-02: Require restore_nonce token and explicit confirmation (--rebuild-mac) for PendingRebuild - F-01: Extend canonical MAC transcript to include chunk generation tuples (node_id, chunk_index, generation) and support transparent legacy migration - F-03: Make V2-to-V3 container upgrade atomic with transactional rollback and dual-slot version update - Bump version to 0.9.4 and update changelog and security docs
This commit is contained in:
@@ -5,6 +5,28 @@ Alle nennenswerten Änderungen an diesem Projekt werden in dieser Datei dokument
|
||||
Das Format basiert auf [Keep a Changelog](https://keepachangelog.com/de/1.1.0/)
|
||||
und dieses Projekt folgt den Richtlinien von [Semantic Versioning](https://semver.org/lang/de/).
|
||||
|
||||
## [0.9.4] - 2026-09-22
|
||||
|
||||
### Format-V3 Systembindung & Integritäts-Härtung (F-01, F-02, F-03)
|
||||
Dieses Patch-Release schließt kritische Bindungs- und Replay-Schwächen im Format-V3-Kryptosystem. Es behebt den PendingRebuild-Bypass bei Header-Wiederherstellungen (F-02), integriert Chunk-Generationen in das kanonische Metadaten-MAC-Transcript zur Abwehr von Content-Replay-Angriffen gleicher Dateigröße (F-01) und stellt die vollständige Transaktions-Atomarität des Format-Upgrades auf V3 sicher (F-03).
|
||||
|
||||
#### Sicherheits-Fixes
|
||||
- **F-02 (HOCH): Schließung des PendingRebuild-Bypasses bei manipuliertem Header**:
|
||||
- *Problem / Bypass in v0.9.2 und v0.9.3*: Die Prüfung `metadata_gen == 0 && metadata_mac IS NULL -> PendingRebuild` erlaubte einem Angreifer mit Schreibzugriff auf die Containerdatei, `meta` auf `NULL` zu setzen und Decoy-Dateien umzubenennen/zu verschieben. Der nächste legitime `sanctum mount` signierte die Manipulation stillschweigend.
|
||||
- *Fix*: Header-Wiederherstellungen via `restore_header_backup` erzeugen nun ein 32-Byte CSPRNG-Token `restore_nonce` in `meta`. `PendingRebuild` wird ausschließlich akzeptiert, wenn dieses Token vorhanden und `metadata_gen == 0` ist.
|
||||
- *Autorisierungszwang*: `sanctum mount` erfordert nach einem Restore zwingend das neue Flag `--rebuild-mac` oder eine explizite interaktive Eingabe von `JA` mit lauter Sicherheitswarnung. `-y` allein autorisiert keinen Rebuild. `NULL`-MAC ohne Restore-Token wird strikt als `Invalid` abgewiesen (`bail!`). Nach erfolgreichem Rebuild wird `restore_nonce` gelöscht.
|
||||
- **F-01 (HOCH): Chunk-Generation-Replay im Transcript & Transkript-Bindung**:
|
||||
- *Problem*: K-02 band die `generation` lediglich in die AAD der gleichen Zeile ein. Ein Angreifer konnte eine Datei gleicher Größe überschreiben und anschließend eine alte Chunk-Zeile (ct, nonce, tag, generation) zurückkopieren. Da das K-01 Transcript bisher nur `chunk_count` umfasste, blieb der Metadaten-MAC gültig und die AEAD-Entschlüsselung lieferte unbemerkt veralteten Klartext. K-02 ohne Transcript-Bindung war kein vollständiger Speicher-Replay-Schutz.
|
||||
- *Fix*: Das kanonische Transcript pro Vault wurde um sortierte Chunk-Tupel erweitert:
|
||||
`ORDER BY node_id, chunk_index: node_id LE64 ‖ chunk_index LE32 ‖ generation LE64` (kein Ciphertext im MAC).
|
||||
Jede Schreiboperation (`write_chunk_and_update_size`, Truncate, Delete) bindet die neuen Generationen in den Metadaten-MAC ein.
|
||||
- *Migration bestehender V3-Container (§7)*: Ältere v0.9.2/v0.9.3-Container werden gegen das bisherige Knoten-Transcript geprüft. Ist der alte MAC valide (`LegacyValid`), wird das Transcript beim ersten Mounten transparent auf das neue Format mit Chunk-Generationen aktualisiert. Bei ungültigem MAC bricht Sanctum fail-closed ab.
|
||||
- *Test-Präzisierung*: Der bestehende AAD-Test in `src/crypto.rs` wurde in `test_k02_chunk_generation_aead_binding` umbenannt, um klarzustellen, dass er nur die AEAD-Bindung im Header und nicht den Replay-Schutz gegen Zeilen-Ersetzung nachweist. Ein neuer End-to-End-Test verifiziert den Replay-Schutz gegen Zeilen-Ersetzung.
|
||||
- **F-03 (HOCH): upgrade_to_v3 Transaktions-Atomarität & Dual-Slot-Konsistenz**:
|
||||
- *Problem*: `upgrade_to_v3` übersprang fehlerhafte Chunks mit `if let Ok(...)` stumm, aktualisierte nur Slot 0 auf `version = 3`, ließ Slot 1 auf Version 2 zurück und meldete fälschlich Erfolg. Bei Hidden-Mounts führte die inkonsistente Slot-Version zu AAD-Fehlern.
|
||||
- *Fix*: Das gesamte Format-Upgrade läuft nun in einer einzigen atomaren SQLite-Transaktion. Fehler bei `decrypt_chunk` oder `encrypt_chunk` brechen sofort via `?` ab und rollen die Transaktion vollständig zurück (`version` bleibt 2, keine halben V3-Zeilen). Chunks, die nicht mit DEK_0 entschlüsseln, brechen fail-closed ab (bei Legacy-Hidden wird das zweite Passwort verlangt).
|
||||
- *Synchrone Versionierung*: Nach erfolgreichem Durchlauf wird `version = 3` synchron für Slot 0 und Slot 1 (sowie Dummy-Slots) gesetzt. Slot 0 Metadaten-MAC wird aufgebaut; Slot 1 nur, falls echte SQLite-Knoten unter Root 2 existieren. Carrier-Inner bleibt Carrier-AEAD.
|
||||
|
||||
## [0.9.3] - 2026-09-21
|
||||
|
||||
### Sicherheits-Governance, Supply-Chain-Audit & Dokumentationsabgleich
|
||||
|
||||
Reference in New Issue
Block a user