release: v0.7.1 — Security-Patch (R-01 bis R-06)
Sanctum Release / Build & Release (Windows x86_64) (push) Waiting to run
Sanctum Release / Build & Release (Windows x86_64) (push) Waiting to run
- 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:
@@ -1,4 +1,4 @@
|
||||
use std::collections::HashSet;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
use rand::rngs::OsRng;
|
||||
use rand::RngCore;
|
||||
@@ -109,5 +109,71 @@ fn test_carrier_protection_in_storage_and_sync() {
|
||||
let carrier_rec = db.get_node_by_id(carrier_node_id).unwrap();
|
||||
assert!(carrier_rec.is_some(), "Carrier-Knoten muss nach Sync unversehrt vorhanden sein");
|
||||
|
||||
// 5. R-02: sync_single_file_to_host muss Carrier-Pull strikt ablehnen
|
||||
let carrier_node = db.get_node_by_id(carrier_node_id).unwrap().unwrap();
|
||||
let local_dest_file = std::env::temp_dir().join(format!("carrier_leak_{}.iso", std::process::id()));
|
||||
let pull_single_res = sanctum::sync::sync_single_file_to_host(
|
||||
&db,
|
||||
0,
|
||||
&dek_0,
|
||||
sanctum::crypto::FORMAT_VERSION,
|
||||
&carrier_node,
|
||||
&local_dest_file,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
assert!(pull_single_res.is_err(), "sync_single_file_to_host auf Carrier muss fehlschlagen");
|
||||
assert!(!local_dest_file.exists(), "Trägerdatei darf niemals auf den Host geschrieben werden");
|
||||
|
||||
// 6. R-02: run_sync mit Pull muss die Trägerdatei überspringen
|
||||
let local_pull_dir = std::env::temp_dir().join(format!("sanctum_pull_test_{}", std::process::id()));
|
||||
let sync_options = sanctum::sync::SyncOptions {
|
||||
direction: sanctum::sync::SyncDirection::Pull,
|
||||
delete: false,
|
||||
dry_run: false,
|
||||
checksum: false,
|
||||
exclude_patterns: Vec::new(),
|
||||
quiet: true,
|
||||
};
|
||||
let pull_res = sanctum::sync::run_sync(
|
||||
&db,
|
||||
0,
|
||||
&dek_0,
|
||||
sanctum::crypto::FORMAT_VERSION,
|
||||
"/",
|
||||
&local_pull_dir.to_string_lossy(),
|
||||
&sync_options,
|
||||
);
|
||||
assert!(pull_res.is_ok(), "run_sync pull muss erfolgreich durchlaufen");
|
||||
let pulled_carrier = local_pull_dir.join(carrier_name);
|
||||
assert!(!pulled_carrier.exists(), "Trägerdatei darf bei recursive pull nicht auf den Host kopiert werden");
|
||||
let _ = std::fs::remove_dir_all(&local_pull_dir);
|
||||
|
||||
// 7. R-02: VFS Copy Schutz
|
||||
let fs = sanctum::vfs::SanctumFs::with_carrier(
|
||||
db.clone(),
|
||||
dek_0.clone(),
|
||||
Some(dek_0.clone()),
|
||||
Some(carrier_node_id),
|
||||
sanctum::crypto::FORMAT_VERSION,
|
||||
false,
|
||||
0,
|
||||
);
|
||||
use dav_server::davpath::DavPath;
|
||||
use dav_server::fs::DavFileSystem;
|
||||
// Copy Quelle = Carrier
|
||||
let from_carrier = DavPath::new(&format!("/{}", carrier_name)).unwrap();
|
||||
let to_copy = DavPath::new("/carrier_copy.iso").unwrap();
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
let copy_src_res = rt.block_on(fs.copy(&from_carrier, &to_copy));
|
||||
assert!(copy_src_res.is_err(), "SanctumFs::copy mit Carrier als Quelle muss FsError::Forbidden liefern");
|
||||
|
||||
// Copy Ziel = Carrier
|
||||
let _regular_file = db.create_node_in_vault(0, 1, "regular.txt", false, &dek_0).unwrap();
|
||||
let from_regular = DavPath::new("/regular.txt").unwrap();
|
||||
let to_carrier = DavPath::new(&format!("/{}", carrier_name)).unwrap();
|
||||
let copy_dst_res = rt.block_on(fs.copy(&from_regular, &to_carrier));
|
||||
assert!(copy_dst_res.is_err(), "SanctumFs::copy mit Carrier als Ziel muss FsError::Forbidden liefern");
|
||||
|
||||
let _ = std::fs::remove_file(&path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user