16 KiB
16 KiB
Sanctum Security Audit & Remediation Log (v0.9.0)
Dieses Dokument fasst alle 39 Findings aus drei umfassenden externen Sicherheitsaudits zusammen, dokumentiert die angewandten Härtungsmaßnahmen, referenziert die jeweiligen Git-Commits und benennt die zugehörigen automatisierten Regressionstests. Abschnitt 5 dokumentiert die Formaterweiterung Carrier V2 (Paged Manifest) aus v0.9.0.
Audit-Zusammenfassung
- Zielversion: Sanctum v0.9.0 (Basis v0.8.1 Audit-Abschluss)
- Behobene Findings: 39 / 39 (100%)
- Test-Ergebnis: 130 / 130 Tests erfolgreich (100% Pass Rate)
- Quality Gates:
cargo fmt --check(100% sauber),cargo clippy --all-targets -- -D warnings(0 Warnungen) - Container-Format: Container-Format V3 mit kanonischer Metadaten-Authentifizierung (HMAC-SHA256) und Chunk-Replay-Schutz (Generation-gebundenes AAD).
- Hidden Vault & Storage-Resilienz: Carrier-Format V2 (Paged Manifest), Dual-Block rollierender Superblock (C-02), Manifest-Entkopplung mit Dirty-Tracking (C-03), Fail-Soft Inode-Isolation (D-01), Sekundärindex (D-02), dynamische Kapazitätsskalierung und Blockwarnung, Fail-Closed Node-Name-Decryption (ST-01), rekursive Fehleraggregation (ST-02) und atomare SQLite-Transaktionen für Baum-Löschungen (ST-03).
Übersicht aller Findings
| Finding | Priorität | Modul | Kurzbeschreibung | Commit | Status & Regressionstest |
|---|---|---|---|---|---|
| C-02 | HOCH | carrier |
Single Point of Failure beseitigt: Rollierendes Dual-Block-Manifest (Block 0 & 1, manifest_generation) mit transparenter Failover-Wiederherstellung |
8455dc0 |
✅ Bestanden (test_c02_dual_block_rolling_manifest_redundancy_and_recovery) |
| C-03 | MITTEL | carrier, vfs, mount |
Entkopplung der Manifest-Neuverschlüsselung via Dirty-Tracking; synchrone Sicherung bei File-Flush und Unmount | c606fa8 |
✅ Bestanden (test_c03_manifest_dirty_decoupling_and_unmount_flush) |
| C-04 | NIEDRIG | carrier, mount, doc |
Dokumentation der Hidden-Vault-Kapazität (~7.000 Inodes) & automatische 80%-Füllstandswarnung beim Mounten | c21d63a |
✅ Bestanden (test_c04_manifest_capacity_limit_and_warning) |
| ST-01 | MITTEL | storage |
Fail-Closed bei Knotennamen-Entschlüsselung; Beseitigung von Hex-Ciphertext-Leaks bei Bitrot/Korruption | dd6b6ff |
✅ Bestanden (test_st01_fail_closed_name_decryption_no_hex_leak) |
| ST-02 | NIEDRIG | storage |
Fehleraggregation beim rekursiven Löschen in delete_node ohne stilles Verschlucken |
efddc2c |
✅ Bestanden (test_st02_recursive_delete_error_propagation_not_swallowed) |
| ST-03 | NIEDRIG | storage |
Atomare SQLite-Transaktion (tx.commit() / Rollback) beim rekursiven Löschen in delete_node |
8ff426d |
✅ Bestanden (test_st03_recursive_delete_transaction_rollback) |
| S-01 | HOCH | sync |
--delete löscht keine ausgeschlossenen Pfade mehr; Schutz ganzer Verzeichnisbäume; --delete-excluded eingeführt |
374150e |
✅ Bestanden (test_s01_delete_preserves_excluded_files_and_directories, test_s01_pull_delete_preserves_local_excluded_and_leak_files) |
| V-02 | HOCH | vfs |
Fehlender Chunk innerhalb erwarteter Dateigröße löst E/A-Fehler aus statt stiller Dateikürzung | 5337644 |
✅ Bestanden (test_v02_missing_chunk_returns_error_instead_of_silent_truncation) |
| V-01 | HOCH | vfs, carrier |
copy() delegiert im Carrier-Modus korrekt an CarrierFs |
151fdba |
✅ Bestanden (test_v01_carrier_fs_copy_delegation_and_functionality) |
| K-01 | HOCH | crypto, storage, verify |
Format V3: Kanonische Metadaten-Authentifizierung via HMAC-SHA256 über alle Inodes | ad531d8 |
✅ Bestanden (test_k01_metadata_tampering_detected_by_verify, test_k01_upgrade_format_v2_to_v3) |
| K-02 | HOCH | crypto, storage |
Format V3: Chunk-Replay-Schutz mittels 24-Byte AAD (inkl. monotoner Generation) | 36a4094 |
✅ Bestanden (test_k02_chunk_replay_protection_with_generation_aad, test_k02_chunk_replay_detected_by_vfs_and_crypto) |
| K-03 | HOCH | crypto, recovery, cli |
Notfallblatt bleibt bei passwd dauerhaft gültig; sanctum rekey zur Schlüsselrotation |
bdddd81 |
✅ Bestanden (test_k03_passwd_sheet_remains_valid_and_rekey_revokes_old_sheet) |
| S-02 | MITTEL | sync |
Plattformunabhängiger Pfad-Zusammenbau und Traversal-Schutz | 7b0f061 |
✅ Bestanden (test_s02_platform_independent_path_construction_and_traversal_rejection) |
| S-03 | MITTEL | sync |
Symlink-Erkennung, Zählung und Zyklenschutz | 888c86c |
✅ Bestanden (test_s03_symlink_skipping_and_cycle_protection) |
| S-04 | MITTEL | sync |
Beseitigung von TOCTOU bei Dateigrößen durch Verwendung von bytes_written |
f557a9d |
✅ Bestanden (test_s04_toctou_file_size_uses_bytes_written) |
| S-05 | MITTEL | sync |
Vollständiges Löschen und Schreddern aller Chunks beim Kürzen auf 0 Bytes | 9634beb |
✅ Bestanden (test_s05_zero_byte_file_truncate_removes_all_chunks) |
| S-06 | MITTEL | storage, mount, sync |
Advisory Lock in Metadaten verhindert parallelen Mount & gleichzeitige Schreibzugriffe | f9733df |
✅ Bestanden (test_s06_advisory_lock_blocks_sync_and_force_overrides) |
| V-03 | MITTEL | vfs, windows |
RAII Memory Lock Guard verhindert vorzeitiges Freigeben gesperrter Speicherseiten beim Klonen | 5285962 |
✅ Bestanden (test_vfs_memory_lock_retention_on_clone_v03) |
| M-01 | MITTEL | crypto |
Erhöhung der Argon2id Standardparameter auf 256 MiB RAM und 4 Iterationen | a502845 |
✅ Bestanden (test_m01_default_kdf_params_256mib_4_iterations) |
| M-02 | MITTEL | build |
Aktivierung von overflow-checks = true im Release-Profil |
ad9148d |
✅ Bestanden (test_m02_release_profile_enables_overflow_checks) |
| M-03 | MITTEL | mount, doc |
Ausgabe von WebDAV-Zugangsdaten und Dokumentation manueller Mount-Befehle unter Linux | 2af14ee |
✅ Bestanden (test_m03_format_linux_mount_instructions) |
| M-04 | MITTEL | doc, threat_model |
Dokumentation des Bedrohungsmodells für Session-Tokens im Nutzerkontext | e496c41 |
✅ Bestanden (Dokumentiert in README.md, THREAT_MODEL.md) |
| M-05 | MITTEL | crypto, storage |
Verifikation der Schemagleichheit zwischen Standard- und Alibi-/Carrier-Containern | a2c16ed |
✅ Bestanden (test_m05_deniability_schema_equality_standard_vs_hidden) |
| V-05 | NIEDRIG | vfs |
Protokollierung von Flush-Fehlern als error! in SanctumFile::drop und zwingender Flush bei close |
17ac4f9 |
✅ Bestanden (test_v05_sanctum_file_drop_flushes_dirty_chunk_automatically) |
| V-06 | NIEDRIG | vfs |
Sparse Writes: Null-Auffüllung von Lücken zwischen Dateiende und Seek-Offset | e300a76 |
✅ Bestanden (test_v06_sparse_write_zero_fills_gap) |
| V-07 | NIEDRIG | vfs |
RFC-4918 konforme Overwrite-Semantik und Verzeichnis-Konfliktprüfungen in copy |
7303934 |
✅ Bestanden (test_v07_copy_overwrite_existing_file_semantics) |
| V-08 | NIEDRIG | vfs, pathutil |
Disallow Tabulator-Steuerzeichen (0x09) in validate_path_safety |
708da24 |
✅ Bestanden (test_path_safety_rejects_null_bytes_and_control_chars) |
| V-09 | NIEDRIG | storage |
Kryptografisches Schreddern von Datenblöcken vor physischer Chunk-Löschung in truncate_chunks_after |
1ba67cc |
✅ Bestanden (test_v09_truncate_chunks_after_shreds_before_deletion) |
| S-07 | NIEDRIG | sync |
Überspringen ungültiger Windows-Dateinamen (files_skipped_invalid) ohne Sync-Abbruch |
15adf79 |
✅ Bestanden (test_s07_skip_invalid_windows_filenames_push_and_pull) |
| S-08 | NIEDRIG | sync |
Präzisierung und Dokumentation des Glob- und Pfad-Matchings | 92db21d |
✅ Bestanden (test_s08_refined_glob_and_directory_exclusions) |
| S-09 | NIEDRIG | sync |
Schutz vor unbeabsichtigtem Überschreiben bei sync pull |
c7c0ed8 |
✅ Bestanden (test_s09_pull_backup_and_update_conflict_safety) |
| U-01 | NIEDRIG | upgrade |
Erzwingen von Pre-Hashing (allow_legacy = false) bei Minisign-Verifikation |
78a9c23 |
✅ Bestanden (test_u01_reject_legacy_unhashed_signature) |
| U-02 | NIEDRIG | upgrade |
Validierung der Release-Version im Minisign trusted comment gegen den Release-Tag |
8dd5449 |
✅ Bestanden (test_u02_validate_trusted_comment_version_matching, test_u02_reject_mismatched_release_tag_replay) |
| U-03 | NIEDRIG | upgrade |
Konfiguration eines sekundären Backup-Release-Public-Keys | bb86447 |
✅ Bestanden (test_u03_verify_signature_with_backup_key_fallback, test_u03_verify_signature_rejects_untrusted_third_party_key) |
| Z-01 | NIEDRIG | mount |
Schutz des Alibi-/Decoy-Passworts im Speicher via Zeroizing<String> |
07afe34 |
✅ Bestanden (test_z01_decoy_password_zeroize_memory) |
| Z-02 | NIEDRIG | storage |
Robuste Wiederherstellung bei vergiftetem SQLite-Mutex (PoisonError) |
5a1fd7c |
✅ Bestanden (test_z02_poisoned_sqlite_mutex_recovery) |
| Z-03 | NIEDRIG | mount, doc |
Dokumentation der Forensik-Eigenschaften von temporären WAL- und SHM-Dateien | 487f999 |
✅ Bestanden (test_wal_and_shm_cleanup_on_close) |
| Z-04 | NIEDRIG | vfs |
Implementierung des WebDAV Quota-Reports (DAV:quota-available-bytes, DAV:quota-used-bytes) |
17908a6 |
✅ Bestanden (test_z04_webdav_quota_report) |
| V-04 | NIEDRIG | vfs, carrier, mount |
Strukturierter Anti-Leak Shield (Exakt, Präfixe, Suffixe, ADS, .trash*) & benutzerdefinierte Filterliste |
45572b7 |
✅ Bestanden (test_is_leak_file, test_v04_custom_anti_leak_rules_and_loader) |
Detaillierte Beschreibungen der Kernarchitektur-Härtungen
1. Container-Format V3 (K-01 & K-02)
- Format-Version: Neue Container werden mit Format V3 (
format_version = 3) erzeugt. - Kanonische Metadaten-Authentifizierung (K-01):
- Alle Inodes des Containers werden kanonisch serialisiert (
id,parent_id,name,is_dir,size,created_at,modified_at,is_carrier,chunk_count). - Eine HMAC-SHA-256 MAC wird über diese Struktur berechnet. Der MAC-Schlüssel wird deterministisch per HKDF-SHA256 aus dem DEK abgeleitet (
SANCTUM_META_MAC_V3). - Der MAC-Wert und ein monotoner Zähler (
metadata_gen) werden in der Tabellemetaabgelegt. - Jede Modifikation aktualisiert die MAC.
sanctum verifydetektiert jegliche unbefugte Manipulation an Metadaten sofort. - Bestehende V1/V2 Container können mit
sanctum upgrade-format --path <container>unterbrechungsfrei auf V3 migriert werden.
- Alle Inodes des Containers werden kanonisch serialisiert (
- Chunk-Replay-Schutz (K-02):
- Jeder Chunk besitzt nun ein Attribut
generationin der Tabellechunks. - Bei jeder Überschreibung eines Datenblocks wird die Generation inkrementiert.
- Das Additional Authenticated Data (AAD) für AES-256-GCM wurde für V3 von 16 Bytes auf 24 Bytes erweitert (
node_id || chunk_index || generation). - Ein Wiedereinspielen eines älteren gültigen Ciphertexts führt unweigerlich zu einem Authentifizierungsfehler (
AEAD decrypt error).
- Jeder Chunk besitzt nun ein Attribut
2. Notfallblatt-Management & Rekeying (K-03)
- Die BIP-39 Notfallkarte kodiert direkt den Master-Verschlüsselungsschlüssel (DEK). Bei einer Passwortänderung (
sanctum passwd) bleibt der DEK intakt, sodass das ausgedruckte Notfallblatt unverändert gültig bleibt. - Um ein kompromittiertes Notfallblatt zu invalidieren, wurde das Kommando
sanctum rekeyeingeführt:- Generiert einen frischen DEK.
- Entschlüsselt alle Chunks und verschlüsselt sie mit dem neuen DEK (und frischer Generation).
- Schreddert die alten Chunks unwiderruflich im Freispeicher.
- Generiert eine neue 24-Wort Notfallphrase für den Nutzer.
3. Anti-Leak Shield Upgrade (V-04)
- Vollständige Trennung der Filterregeln in strukturierte Kategorien:
- Exakte Namen:
thumbs.db,desktop.ini,folder.jpg,.ds_store,.directory,.fseventsd,.spotlight-v100. - Präfixe:
~$*(Office-Temporärdateien),._*(AppleDouble Resource Forks). - Suffixe:
.tmp,.temp,.crdownload,.part,.partial,~*(Editor-Backups). - NTFS Alternate Data Streams (ADS): Alle Zugriffe mit
:(z. B.Zone.Identifier). - Wildcards:
.trash*.
- Exakte Namen:
- Option
--anti-leak-list <FILE>für benutzerdefinierte Ausschlussmuster.
4. Carrier-Manifest-Resilienz & Storage-Hygiene (Dritte Audit-Runde)
- Rollierendes Dual-Block-Manifest (C-02):
- Das Carrier-Manifest wird abwechselnd auf Block 0 und Block 1 geschrieben, geschützt durch ein monotones Generation-Attribut (
manifest_generation: u64). - Beim Mounten liest Sanctum beide Blöcke. Ist ein Block korrumpiert (z. B. Bitrot oder unvollständiges Schreiben), stellt Sanctum den Hidden Vault transparent aus der intakten Kopie wieder her.
- Das Carrier-Manifest wird abwechselnd auf Block 0 und Block 1 geschrieben, geschützt durch ein monotones Generation-Attribut (
- Entkopplung der Manifest-Neuverschlüsselung (C-03):
- Vor v0.8.1 wurde bei jeder Metadatenänderung (Dateierstellung, Ordnererstellung, Löschen, Umbenennen, Drop) das gesamte 1-MB-Manifest synchron per AES-256-GCM neu verschlüsselt.
- v0.8.1 führt Dirty-Tracking ein: Änderungen markieren das Manifest als
dirty. Die tatsächliche Verschlüsselung erfolgt gebündelt bei Datei-flush(), Unmount/Drop oder nach 50 Operationen.
- Kapazitätsgrenze & Warnschwelle (C-04):
- Durch den 1-MB-Block für das Manifest ergibt sich eine empfohlene Obergrenze von ~7.000 Inodes im Hidden Vault.
- Ab 80% Füllstand (~838 KB) warnt Sanctum beim Mounten und Speichern unübersehbar.
- Fail-Closed bei Knotennamen (ST-01):
- Bei Fehlschlagen der Entschlüsselung von Knotennamen werden keine Hex-Ciphertext-Fragmente mehr exponiert (
unwrap_or(enc_name)eliminiert). - Unlesbare Knoten werden mit
warn!geloggt und inlist_children_in_vault,resolve_path_in_vaultundget_node_by_id_in_vaultfail-closed übersprungen.
- Bei Fehlschlagen der Entschlüsselung von Knotennamen werden keine Hex-Ciphertext-Fragmente mehr exponiert (
- Fehleraggregation & Transaktions-Rollback bei rekursivem Löschen (ST-02 & ST-03):
- Fehler beim Löschen von Kindknoten werden nicht mehr ignoriert (
let _ =eliminiert), sondern aggregiert und protokolliert.
- Fehler beim Löschen von Kindknoten werden nicht mehr ignoriert (
5. Sanctum v0.9.0 — Formaterweiterung Carrier V2 (Paged Manifest)
- Aufhebung der C-04 Manifest-Kapazitätsgrenze:
- In v0.8.1 war das Manifest ein einzelnes JSON-Objekt auf Block 0 und Block 1 (limitiert auf ca. 7.000 Inodes).
- Mit Format V2 wird der
CarrierSuperblock(Block 0 & 1, dual-block rollierend C-02) von den eigentlichen Inode-Daten entkoppelt. - Inodes werden in separaten
CarrierInodePage-Blöcken (~1 MB Payload je Seite, ca. 4.500–7.000 Inodes pro Seite) verwaltet, dynamisch allokiert aus dem Blockpool.
- Paged Loading & Fail-Soft Resilienz (D-01):
- Isolierte Fehlerbehandlung: Beschädigte oder unlesbare Inode-Seiten führen nicht mehr zum Gesamtabbruch des Mounts.
- Das System lädt alle lesbaren Seiten, loggt fehlerhafte Seiten als
error!und führt einen Zählercorrupted_pages, der beim Einbinden gut sichtbar gemeldet wird.
- Sekundärindex für Kindknoten (
children_index, D-02):CarrierFsInnerpflegt einenHashMap<i64, Vec<i64>>In-Memory Index für Vater-Kind-Beziehungen.- Reduziert Pfadauflösung (
resolve_path) und Verzeichnis-Listings (read_dir) vonO(N)Tabellenscans aufO(\text{Geschwister}).
- Transparente Migration & Allokations-Sicherheit (D-03, D-04, D-05):
- V1-Container werden transparent geladen und beim ersten Schreibvorgang nach V2 migriert — inklusive Vorabprüfung, ob genügend freie Blöcke vorhanden sind.
- Freigabe überzähliger Seitenblöcke (
shred_carrier_block) bei Inode-Löschungen. - Ersetzung der statischen 80%-Füllstandswarnung durch eine Block-Verfügbarkeitswarnung bei
< 20freien Blöcken oder< 5%Restkapazität.
- Automatisierte Testabdeckung: 7 neue Regressionstests in
tests/carrier_v2_paged_manifest_test.rsdecken Kapazität (>10.000 Inodes), Migration, Fail-Soft-Isolation, Sekundärindex-Konsistenz, Pfadauflösungs-Performance, Out-of-Space-Abbruch und Blockfreigabe ab (Gesamttests: 130/130 erfolgreich).
Verifikationsnachweis
Alle Unit- und Integrationstests wurden auf einem Windows x86_64 Host mit 100% Erfolgsquote ausgeführt (130 / 130 Tests). Die Release-Paketierung für Windows und Linux musl ist voll automatisiert und wird mit Minisign kryptografisch abgesichert.