fix(web): redact database error details from API responses - #1711
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a centralized db_error helper function to prevent leaking internal database details in API responses and adds a corresponding unit test. While this is a positive change, the implementation is incomplete as several other locations in the file still convert database errors directly to strings, potentially exposing sensitive information. It is recommended to apply this masking consistently across all error handlers and consider using specific error variants for better semantic clarity.
| fn db_error(context: &str, e: impl std::fmt::Display) -> (StatusCode, String) { | ||
| tracing::error!(%e, context, "Database error in jobs handler"); | ||
| ( | ||
| StatusCode::INTERNAL_SERVER_ERROR, | ||
| "Internal database error".to_string(), | ||
| ) | ||
| } |
There was a problem hiding this comment.
This is a great addition to prevent leaking database error details. However, the fix is incomplete as there are several other places in this file where database errors are directly converted to strings and returned in the API response (e.g., lines 301, 343, 420, 460, 664, 708, 776). This can still leak sensitive implementation details. Please ensure all database error conversions are handled by masking internal details. Consider creating specific error variants for different failure modes to provide semantically correct messages. Note: Avoid including function names or source code layout in error messages. Additionally, ensure that sensitive commands like process restarts are restricted to securely authenticated channels, and verify that the authenticated user ID matches the resource owner's ID before performing operations.
References
- Avoid coupling log messages to implementation details like configuration interfaces or source code layout. The underlying error message should provide sufficient context on its own.
- Create specific error variants for different failure modes (e.g., DownloadFailed with a URL string vs. ManifestRead with a file path) to provide semantically correct and clear error messages.
- Tools that interact with user-owned resources, such as sandbox jobs, must verify that the authenticated user ID in the tool context matches the resource owner's ID (e.g., by using a ContextManager) before performing any read or write operations to prevent unauthorized cross-user access.
- Restrict highly sensitive commands, like process restart, to a specific, securely authenticated channel (e.g., a web gateway with a single admin token) to prevent unauthorized use in multi-user environments.
zmanian
left a comment
There was a problem hiding this comment.
Approve. Correct fix for DB error detail leakage. All 8 instances in jobs.rs replaced with generic message + tracing::error. Minor suggestion: use more specific context per handler (e.g., "jobs_list", "jobs_cancel") instead of "jobs_handler" for all 8.
Code reviewFound 3 issues:
The macro on line 19 passes ironclaw/src/channels/web/handlers/jobs.rs Lines 18 to 24 in 9bb19a9 Correct syntax: tracing::error!(error = %e, context = context, "Database error in jobs handler");
Per
All database error paths should use the ironclaw/src/channels/web/handlers/jobs.rs Line 300 in 9bb19a9
All calls to ironclaw/src/channels/web/handlers/jobs.rs Lines 224 to 226 in 9bb19a9 |
Summary
The jobs API handlers were formatting full database exception messages into HTTP responses via
format!("Database error: {}", e), potentially exposing internal implementation details (table names, query structure, connection errors) to API clients.db_error()helper that logs the full error viatracing::error!and returns a generic"Internal database error"to the clientserver.rswhich already handled this correctlyFixes #1702
Test plan
test_db_error_does_not_leak_details— verifies returned body contains no DB-specific stringscargo checkcargo fmt