fix(security): apply 4 vulnerability fixes from security audit

1. Share password bypass (HIGH): enforce password check in get_shared_link_by_token,
   verify_shared_link_password now returns ShareDto only on correct password.
2. WebDAV MOVE ownership (MEDIUM): add assert_owner on destination parent folder
   for file moves in both PathResolver and legacy branches.
3. Path traversal defense-in-depth (LOW): add reject_path_traversal() to WebDAV,
   CalDAV, and CardDAV handlers rejecting '..' segments at HTTP boundary.
4. Setup race condition (LOW): atomic INSERT ... ON CONFLICT DO NOTHING in
   try_claim_initialization prevents duplicate admin creation.
This commit is contained in:
Dionisio
2026-03-05 16:09:37 +01:00
parent 33cfb0faef
commit 4197cc3b7b
9 changed files with 198 additions and 14 deletions
@@ -80,6 +80,7 @@ async fn handle_caldav_methods(
) -> Result<Response<Body>, AppError> {
let uri = req.uri().clone();
let path = extract_caldav_path(uri.path());
reject_path_traversal(&path)?;
handle_caldav_methods_inner(state, req, path).await
}
@@ -119,6 +120,18 @@ fn extract_caldav_path(uri_path: &str) -> String {
percent_decode_str(encoded).decode_utf8_lossy().into_owned()
}
/// Reject paths that contain path-traversal segments (`.` or `..`).
fn reject_path_traversal(path: &str) -> Result<(), AppError> {
for segment in path.split('/') {
if segment == ".." || segment == "." {
return Err(AppError::bad_request(
"Path must not contain '.' or '..' segments",
));
}
}
Ok(())
}
// ─── Helper: extract user from request ───────────────────────────────
fn extract_user(req: &Request<Body>) -> Result<CurrentUser, AppError> {