security: fix vulnerabilities 1-7 from security audit
- Fix #1: Share handler IDOR - enforce owner check on share operations - Fix #2: list_files_query IDOR - bind folder queries to authenticated user - Fix #3: Dedup handler IDOR - restrict dedup operations to file owner - Fix #4: Trash handler OptionalAuthUser - require full AuthUser - Fix #5: Error info leakage - sanitize 500 error responses - Fix #6: Chunked upload IDOR - bind upload sessions to user_id, add verify_session_owner() check on all session operations - Fix #7: CSP unsafe-inline removal - migrate all inline scripts, styles and event handlers to external files, tighten CSP to script-src 'self'; style-src 'self' New files: - static/js/core/theme-init.js (render-blocking theme init) - static/js/core/sw-register.js (service worker registration) - static/css/views/device-verify.css (extracted inline styles) - static/js/views/device-verify/device-verify.js (extracted inline script)
This commit is contained in:
@@ -22,9 +22,14 @@ pub struct AppError {
|
||||
}
|
||||
|
||||
/// JSON response structure for errors.
|
||||
///
|
||||
/// Both `error` and `message` carry the same content for backwards compatibility:
|
||||
/// - Legacy ad-hoc handlers returned `{"error": "..."}` (frontend reads `.error`)
|
||||
/// - AppError returned `{"message": "..."}` (admin panel reads `.message`)
|
||||
#[derive(Serialize)]
|
||||
pub struct ErrorResponse {
|
||||
pub status: String,
|
||||
pub error: String,
|
||||
pub message: String,
|
||||
pub error_type: String,
|
||||
}
|
||||
@@ -133,9 +138,26 @@ impl From<DomainError> for AppError {
|
||||
impl IntoResponse for AppError {
|
||||
fn into_response(self) -> Response {
|
||||
let status = self.status_code;
|
||||
|
||||
// Sanitize 500 Internal Server Error to prevent information leakage.
|
||||
// Log the full error server-side for debugging, return a generic
|
||||
// message to the client. Other status codes (including 5xx like
|
||||
// 501, 503, 507) keep their intentionally user-facing messages.
|
||||
let client_message = if status == StatusCode::INTERNAL_SERVER_ERROR {
|
||||
tracing::error!(
|
||||
error_type = %self.error_type,
|
||||
"Internal server error: {}",
|
||||
self.message
|
||||
);
|
||||
"An internal error occurred. Please try again later.".to_string()
|
||||
} else {
|
||||
self.message
|
||||
};
|
||||
|
||||
let error_response = ErrorResponse {
|
||||
status: status.to_string(),
|
||||
message: self.message,
|
||||
error: client_message.clone(),
|
||||
message: client_message,
|
||||
error_type: self.error_type,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user