fix(security): V-01,V-02,V-04,V-05,V-06 - multiple vulnerability fixes

- V-01: CalDAV unbounded body limit → MAX_CALDAV_BODY = 1MB
- V-02: CardDAV unbounded body limit → MAX_CARDDAV_BODY = 1MB
- V-04: Batch operations without max size → MAX_BATCH_SIZE = 1000
- V-05: WOPI get_editor_url IDOR → authorize_wopi_access with ownership check
- V-06: JWT secret without entropy validation → panic <16, warn 16-31, accept >=32
This commit is contained in:
Dionisio
2026-03-05 16:57:44 +01:00
parent 4197cc3b7b
commit 4d81bcbd7b
5 changed files with 176 additions and 37 deletions
@@ -39,6 +39,10 @@ use crate::interfaces::middleware::auth::CurrentUser;
const HEADER_DAV: HeaderName = HeaderName::from_static("dav");
/// Maximum allowed request body size for CardDAV XML/vCard endpoints (1 MB).
/// Prevents OOM/DoS via unbounded body buffering.
const MAX_CARDDAV_BODY: usize = 1_048_576;
/// Creates CardDAV routes with full path prefixes.
///
/// Uses `merge()` instead of `nest()` to avoid Axum's trailing-slash routing gap.
@@ -181,7 +185,7 @@ async fn handle_propfind(
let addressbook_service = get_addressbook_service(&state)?;
let contact_svc = get_contact_service(&state)?;
let body_bytes = body::to_bytes(req.into_body(), usize::MAX)
let body_bytes = body::to_bytes(req.into_body(), MAX_CARDDAV_BODY)
.await
.map_err(|e| AppError::bad_request(format!("Failed to read request body: {}", e)))?;
@@ -312,7 +316,7 @@ async fn handle_report(
let user = extract_user(&req)?;
let contact_svc = get_contact_service(&state)?;
let body_bytes = body::to_bytes(req.into_body(), usize::MAX)
let body_bytes = body::to_bytes(req.into_body(), MAX_CARDDAV_BODY)
.await
.map_err(|e| AppError::bad_request(format!("Failed to read request body: {}", e)))?;
@@ -381,7 +385,7 @@ async fn handle_mkcol(
let user = extract_user(&req)?;
let addressbook_service = get_addressbook_service(&state)?;
let body_bytes = body::to_bytes(req.into_body(), usize::MAX)
let body_bytes = body::to_bytes(req.into_body(), MAX_CARDDAV_BODY)
.await
.map_err(|e| AppError::bad_request(format!("Failed to read request body: {}", e)))?;
@@ -435,7 +439,7 @@ async fn handle_put(
let address_book_id = parts[0];
let body_bytes = body::to_bytes(req.into_body(), usize::MAX)
let body_bytes = body::to_bytes(req.into_body(), MAX_CARDDAV_BODY)
.await
.map_err(|e| AppError::bad_request(format!("Failed to read request body: {}", e)))?;
@@ -628,7 +632,7 @@ async fn handle_proppatch(
let user = extract_user(&req)?;
let addressbook_service = get_addressbook_service(&state)?;
let body_bytes = body::to_bytes(req.into_body(), usize::MAX)
let body_bytes = body::to_bytes(req.into_body(), MAX_CARDDAV_BODY)
.await
.map_err(|e| AppError::bad_request(format!("Failed to read request body: {}", e)))?;