Mitigation Strategy: Fairing Principle of Least Privilege & Ordering
Mitigation Strategy: Fairing Principle of Least Privilege and Explicit Ordering
Description:
- Identify Fairing Needs: For each custom fairing, list the specific data it needs from the
Request
andResponse
objects. Avoid using&Request
or&Response
if only a small part is needed (e.g., a single header). - Refactor for Minimal Access: Rewrite fairing code to only access the identified data. For example, if a fairing only needs the
Content-Type
header, access it directly viarequest.headers().get_one("Content-Type")
instead of getting the entireRequest
object. - Define Explicit Order: In
rocket::build()
, use.attach()
with a specificFairing
rank (e.g.,Fairing::new(..., rank = 1)
for early,rank = 10
for late). Security-critical fairings (authentication, authorization, input validation) should have lower ranks (run earlier on requests, later on responses). - Document Order and Purpose: Create a comment block in the
main.rs
or fairing module clearly documenting the intended order of fairings and the purpose of each. - Review and Audit: Regularly review fairing code to ensure it adheres to the principle of least privilege and the documented order.
List of Threats Mitigated:
- Information Disclosure (Severity: High): Prevents fairings from accidentally accessing and potentially leaking sensitive data they don't need.
- Authorization Bypass (Severity: High): Ensures security-critical fairings run before fairings that might modify the request in a way that could bypass security checks.
- Injection Attacks (Severity: High): By validating input within fairings that modify the request, we prevent injection attacks from propagating to later stages.
- Denial of Service (DoS) (Severity: Medium): By limiting the scope of fairings, we reduce the potential for a single fairing to consume excessive resources.
Impact:
- Information Disclosure: Significantly reduces the risk by limiting data access.
- Authorization Bypass: Significantly reduces the risk by enforcing a secure execution order.
- Injection Attacks: Reduces the risk by providing an additional layer of defense.
- Denial of Service (DoS): Moderately reduces the risk by limiting the potential impact of a single fairing.
Currently Implemented:
- Partially implemented. Fairing order is defined, but some fairings still have broader access than necessary. Documentation is present but could be more detailed. Located in
src/fairings/
.
Missing Implementation:
- Refactor
AuditLogFairing
insrc/fairings/audit_log.rs
to only access the request method and URI, instead of the entireRequest
object. - Add more detailed comments to
src/main.rs
explaining the rationale behind the specific ranking of each fairing.
Mitigation Strategy: Secure Request Guard Implementation
Mitigation Strategy: Secure Request Guard Implementation with Fail-Closed Logic
Description:
- Identify Spoofable Data: Review all Request Guards and identify any reliance on easily spoofable data (e.g.,
User-Agent
,Referer
, custom headers without cryptographic verification). - Implement Secure Authentication/Authorization: Replace reliance on spoofable data with secure mechanisms, utilizing Rocket's features where appropriate:
- Custom Request Guards for JWTs/Sessions: Create Request Guards that validate JWTs or session identifiers (using Rocket's
Cookies
or a custom fairing for secure cookie handling). - Database Lookups (within Guards): Perform database lookups based on the authenticated user's ID (obtained from a validated token/session) to determine their permissions within the Request Guard.
- Custom Request Guards for JWTs/Sessions: Create Request Guards that validate JWTs or session identifiers (using Rocket's
- Fail Closed: Ensure all Request Guards have a default
Outcome::Failure
that denies access if the guard cannot definitively determine that access should be granted. UseOutcome::Forward
only when the guard is certain about allowing access. - Centralize Logic (if possible): Consolidate authorization logic into a smaller number of well-defined Request Guards (e.g.,
AdminGuard
,UserGuard
). - Unit Test Guards: Create unit tests for each Request Guard, covering various scenarios (valid/invalid tokens, different user roles, missing data). Use Rocket's testing framework (
local::Client
). - Generic Error Responses: Ensure that failed Request Guards return generic 403 Forbidden or 401 Unauthorized responses (using Rocket's
Status
codes), without revealing details about the reason for denial.
List of Threats Mitigated:
- Authentication Bypass (Severity: Critical): Prevents attackers from accessing protected routes by spoofing request data.
- Authorization Bypass (Severity: Critical): Ensures that only users with the correct permissions can access specific resources.
- Information Disclosure (Severity: Medium): Prevents detailed error messages from revealing information about the application's security mechanisms.
Impact:
- Authentication Bypass: Eliminates the risk if implemented correctly.
- Authorization Bypass: Eliminates the risk if implemented correctly.
- Information Disclosure: Significantly reduces the risk.
Currently Implemented:
- Mostly implemented. JWT-based authentication is used for API routes (custom Request Guard). Session-based authentication is used for web routes (custom Request Guard). Fail-closed logic is in place. Unit tests exist for most guards. Located in
src/guards/
.
Missing Implementation:
- Review
src/guards/user_guard.rs
to ensure that the session ID validation is robust against session fixation attacks (e.g., by regenerating the session ID after login - potentially using a custom fairing). - Add integration tests to verify that the interaction between
AuthGuard
andAdminGuard
works as expected (using Rocket'slocal::Client
).
Mitigation Strategy: Secure Multipart Form Handling (using rocket_multipart_form_data
)
Mitigation Strategy: Secure Multipart Form Handling with Strict Limits and Validation (Rocket-Specific)
Description:
- Global Size Limits (rocket.toml): Set global size limits in
rocket.toml
using thelimits
configuration:[limits] data-form = "2 MiB" # Limit for all forms file = "1 MiB" # Limit for individual files
- Per-Field Limits (rocket_multipart_form_data): In your form handling code, use
rocket_multipart_form_data
's features to set per-field limits and perform basic validation:use rocket_multipart_form_data::{mime, MultipartFormDataOptions, MultipartFormDataField, MultipartFormData}; #[post("/upload", data = "<data>")] async fn upload(content_type: &ContentType, data: Data<'_>) -> Result<String, &'static str> { let mut options = MultipartFormDataOptions::with_multipart_form_data_fields( vec![ MultipartFormDataField::file("image") .content_type_by_string(Some(mime::IMAGE_STAR)) // Accept any image type .unwrap() .size_limit(1024 * 1024), // 1MB limit MultipartFormDataField::text("description").size_limit(256), // 256-byte limit ] ); let mut multipart_form_data = MultipartFormData::parse(content_type, data, options).await.unwrap(); // ... (Further processing and validation) ... }
- File Type Validation (Beyond Extensions - within Rocket handler): While
rocket_multipart_form_data
can do basic MIME type checking, perform more robust validation within your Rocket handler using a library likeinfer
to determine the file type based on its content (magic numbers). This is crucial, as thecontent_type
provided by the client can be spoofed. - Safe Filenames (within Rocket handler): Generate random filenames within your Rocket handler using a cryptographically secure random number generator (e.g.,
rand::rngs::OsRng
). Store the original filename separately (if needed) in a database, associated with the random filename. - Path Traversal Prevention (within Rocket handler): Sanitize filenames before saving, within your Rocket handler:
use std::path::PathBuf; fn sanitize_filename(filename: &str) -> PathBuf { // ... (Implementation as before) ... }
List of Threats Mitigated:
- Denial of Service (DoS) (Severity: High): Prevents attackers from uploading excessively large files.
- Path Traversal (Severity: Critical): Prevents attackers from writing files to arbitrary locations.
- Remote Code Execution (RCE) (Severity: Critical): Reduces the risk by validating file types and preventing direct execution (though server-side configuration is also needed).
Impact:
- Denial of Service (DoS): Significantly reduces the risk (using Rocket's
limits
androcket_multipart_form_data
). - Path Traversal: Eliminates the risk if filename sanitization is implemented correctly within the Rocket handler.
- Remote Code Execution (RCE): Reduces the risk (requires additional server-side configuration to fully eliminate).
Currently Implemented:
- Partially implemented. Global size limits are set in
rocket.toml
. Basic extension validation is used (viarocket_multipart_form_data
). Located insrc/routes/upload.rs
.
Missing Implementation:
- Implement magic number-based file type validation within the
upload
handler insrc/routes/upload.rs
, after parsing the multipart form data. - Implement robust filename sanitization using the
sanitize_filename
function (or a similar library) within theupload
handler. - Use
rocket_multipart_form_data
's per-field limits more comprehensively.
Mitigation Strategy: Secure State Management (Rocket's State
)
Mitigation Strategy: Secure State Management with Synchronization
Description:
- Identify Shared State: Identify all data stored in Rocket's managed state (using
rocket::State
). - Use Synchronization: If the state is mutable and accessed by multiple requests concurrently, use
Mutex
orRwLock
to protect it within your Rocket handlers and fairings:#[derive(Debug, Default)] struct Counter(Arc<Mutex<usize>>); #[get("/count")] fn count(counter: &State<Counter>) -> String { let mut count = counter.0.lock().unwrap(); *count += 1; format!("Count: {}", *count) }
- Clear Session State (if applicable): If you have state associated with user sessions (likely managed via a custom fairing and/or Request Guard), ensure it's cleared when the session ends (e.g., on logout). This often involves interacting with Rocket's
Cookies
or a custom session management system.
List of Threats Mitigated:
- Race Conditions (Severity: High): Prevents data corruption due to concurrent access to shared state managed by Rocket.
Impact:
- Race Conditions: Eliminates the risk if synchronization is implemented correctly using Rocket's
State
and appropriate locking mechanisms.
Currently Implemented:
Mutex
is used to protect a shared counter insrc/routes/counter.rs
(accessed viarocket::State
).
Missing Implementation:
- Review
src/state.rs
to see if any other shared state (accessed viarocket::State
) needs synchronization.
Mitigation Strategy: Secure Error Handling (Rocket's Catchers)
Mitigation Strategy: Secure Error Handling with Generic Messages using Rocket's Catchers
Description:
- Custom Error Catchers: Implement custom error catchers using Rocket's
#[catch]
attribute for common HTTP error codes (404, 500, etc.). - Generic Error Messages: In the error catchers, return generic error messages to the user using Rocket's
Response
andStatus
types. Do not include any details about the internal error.#[catch(404)] fn not_found() -> &'static str { "Resource not found." }
- Test Error Catchers: Write unit tests using Rocket's testing framework to verify that your error catchers handle different error conditions correctly and return the expected
Status
codes.
List of Threats Mitigated:
- Information Disclosure (Severity: Medium): Prevents internal error details from being leaked to attackers via error responses.
Impact:
- Information Disclosure: Significantly reduces the risk by ensuring only generic messages are returned to the client, controlled by Rocket's error handling mechanisms.
Currently Implemented:
- Custom error catchers are implemented for 404 and 500 errors using
#[catch]
. Generic error messages are returned. Located insrc/errors.rs
.
Missing Implementation:
- Add unit tests for the custom error catchers using Rocket's testing framework.