release: v0.7.1 — Security-Patch (R-01 bis R-06)
Sanctum Release / Build & Release (Windows x86_64) (push) Canceled after 0s
Sanctum Release / Build & Release (Windows x86_64) (push) Canceled after 0s
- R-01: Bereinigung verbliebener Restbehauptungen in Doku und Code (LEGAL.md, README.md, QUICKSTART.md, main.rs, crypto/storage/recovery/verify.rs) - R-02: Lückenloser Carrier-Schutz in SanctumFs::copy (Quelle & Ziel) und sync (Pull-Skip & Push-Schutz) - R-03: Shared Dateinamen-Validierung (validate_node_name) in pathutil.rs, durchgesetzt in storage.rs und vfs.rs - R-04: Fail-closed Release-Packaging & obligatorische Minisign-Signatur in CI (.gitea/workflows/release.yaml) und Scripts - R-05: Session-Token Beseitigung im argv: In-Process Win32 WNetAddConnection2W/WNetCancelConnection2W, kein gio argv-Token, Multi-Auth HTTP Middleware (Basic Auth, X-Sanctum-Token, Path-Fallback) mit 401 WWW-Authenticate - R-06: Sofortiges Löschen von SANCTUM_RECOVERY_KEY aus der Prozessumgebung
This commit is contained in:
+7
-5
@@ -639,7 +639,7 @@ impl Database {
|
||||
Ok(carrier_node_id)
|
||||
}
|
||||
|
||||
/// Initialisiert das Datenbankschema mit Unterstützung für Plausible Deniability (optionaler Hidden Vault).
|
||||
/// Initialisiert das Datenbankschema mit Unterstützung für Dual-Vault (optionaler Hidden Vault).
|
||||
/// Sowohl Standard-Container als auch Container mit Hidden Vault besitzen eine bit- und schemagleiche Struktur:
|
||||
/// - 2 Slots in der meta-Tabelle (Slot 0 + Slot 1 mit echtem KEK oder ununterscheidbarem CSPRNG-Rauschen)
|
||||
/// - 2 Root-Knoten (id=1 für Vault 0, id=2 für Vault 1)
|
||||
@@ -720,7 +720,7 @@ impl Database {
|
||||
params![now, now],
|
||||
)?;
|
||||
|
||||
// Slot 1: Entweder echter Hidden Vault ODER ununterscheidbares kryptografisches Rauschen (Plausible Deniability)
|
||||
// Slot 1: Entweder echter Hidden Vault ODER CSPRNG-Rauschen (Dummy-Slot-Längenparität)
|
||||
if let Some((h_salt, h_params, h_wrapped, h_nonce, h_tag)) = hidden {
|
||||
let params_json_1 = serde_json::to_string(h_params)?;
|
||||
conn.execute(
|
||||
@@ -758,7 +758,7 @@ impl Database {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Initialisiert das Datenbankschema für einen Standard-Container (mit Dummy-Slot für Plausible Deniability).
|
||||
/// Initialisiert das Datenbankschema für einen Standard-Container (mit Dummy-Slot-Längenparität).
|
||||
pub fn init_schema(
|
||||
&self,
|
||||
salt: &[u8; 16],
|
||||
@@ -1191,6 +1191,7 @@ impl Database {
|
||||
is_dir: bool,
|
||||
dek: &[u8; 32],
|
||||
) -> Result<NodeRecord> {
|
||||
crate::pathutil::validate_node_name(name)?;
|
||||
let now = current_timestamp();
|
||||
let conn = self.conn.lock().unwrap();
|
||||
|
||||
@@ -1299,6 +1300,7 @@ impl Database {
|
||||
dek: &[u8; 32],
|
||||
) -> Result<()> {
|
||||
self.assert_not_carrier(id)?;
|
||||
crate::pathutil::validate_node_name(new_name)?;
|
||||
let now = current_timestamp();
|
||||
let conn = self.conn.lock().unwrap();
|
||||
let stored_name = if vault_id == 1 {
|
||||
@@ -1590,7 +1592,7 @@ impl Database {
|
||||
)?;
|
||||
}
|
||||
|
||||
// Falls Slot 1 nicht existiert (z. B. altes Single-Slot Backup), erzeuge Dummy-Slot für Plausible Deniability
|
||||
// Falls Slot 1 nicht existiert (z. B. altes Single-Slot Backup), erzeuge Dummy-Slot für Längenparität
|
||||
if !has_slot1 {
|
||||
let (dummy_dek, dummy_nonce, dummy_tag, dummy_salt) = generate_dummy_slot();
|
||||
let dummy_params_json = serde_json::to_string(&KdfParams::default())?;
|
||||
@@ -1910,7 +1912,7 @@ mod tests {
|
||||
params![hidden_file.id],
|
||||
|r| r.get(0),
|
||||
).unwrap();
|
||||
// Plausible Deniability: Kein $h$-Präfix, kein Klartext
|
||||
// Dual-Vault Isolation: Kein $h$-Präfix, kein Klartext
|
||||
assert!(!raw_name_v1.starts_with("$h$"), "Hidden Vault Dateiname darf kein $h$-Präfix mehr besitzen");
|
||||
assert!(!raw_name_v1.contains("classified_leak"), "Plaintext darf keinesfalls in SQLite DB auftauchen");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user