Files
sanctum/SECURITY_AUDIT.md
T
harald 3693e03494
Sanctum Release / Build & Test (Windows x86_64) (push) Waiting to run
Sanctum Release / Sign & Release (push) Blocked by required conditions
chore(release): bump version to 0.9.0 and update docs
2026-09-20 00:15:25 +02:00

16 KiB
Raw Permalink Blame History

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 Tabelle meta abgelegt.
    • Jede Modifikation aktualisiert die MAC. sanctum verify detektiert jegliche unbefugte Manipulation an Metadaten sofort.
    • Bestehende V1/V2 Container können mit sanctum upgrade-format --path <container> unterbrechungsfrei auf V3 migriert werden.
  • Chunk-Replay-Schutz (K-02):
    • Jeder Chunk besitzt nun ein Attribut generation in der Tabelle chunks.
    • 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).

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 rekey eingefü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*.
  • 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.
  • 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 in list_children_in_vault, resolve_path_in_vault und get_node_by_id_in_vault fail-closed übersprungen.
  • 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.

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.5007.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ähler corrupted_pages, der beim Einbinden gut sichtbar gemeldet wird.
  • Sekundärindex für Kindknoten (children_index, D-02):
    • CarrierFsInner pflegt einen HashMap<i64, Vec<i64>> In-Memory Index für Vater-Kind-Beziehungen.
    • Reduziert Pfadauflösung (resolve_path) und Verzeichnis-Listings (read_dir) von O(N) Tabellenscans auf O(\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 < 20 freien Blöcken oder < 5% Restkapazität.
  • Automatisierte Testabdeckung: 7 neue Regressionstests in tests/carrier_v2_paged_manifest_test.rs decken 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.