Skip to content

Latest commit

 

History

History
183 lines (142 loc) · 13.2 KB

File metadata and controls

183 lines (142 loc) · 13.2 KB

Mitigation Strategies Analysis for sergiobenitez/rocket

Mitigation Strategy: Fairing Principle of Least Privilege and Explicit Ordering

Description:

  1. Identify Fairing Needs: For each custom fairing, list the specific data it needs from the Request and Response objects. Avoid using &Request or &Response if only a small part is needed (e.g., a single header).
  2. 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 via request.headers().get_one("Content-Type") instead of getting the entire Request object.
  3. Define Explicit Order: In rocket::build(), use .attach() with a specific Fairing 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).
  4. 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.
  5. 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 in src/fairings/audit_log.rs to only access the request method and URI, instead of the entire Request 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 with Fail-Closed Logic

Description:

  1. 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).
  2. 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.
  3. 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. Use Outcome::Forward only when the guard is certain about allowing access.
  4. Centralize Logic (if possible): Consolidate authorization logic into a smaller number of well-defined Request Guards (e.g., AdminGuard, UserGuard).
  5. 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).
  6. 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 and AdminGuard works as expected (using Rocket's local::Client).

Mitigation Strategy: Secure Multipart Form Handling with Strict Limits and Validation (Rocket-Specific)

Description:

  1. Global Size Limits (rocket.toml): Set global size limits in rocket.toml using the limits configuration:
    [limits]
    data-form = "2 MiB"  # Limit for all forms
    file = "1 MiB"      # Limit for individual files
  2. 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) ...
    }
  3. 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 like infer to determine the file type based on its content (magic numbers). This is crucial, as the content_type provided by the client can be spoofed.
  4. 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.
  5. 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 and rocket_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 (via rocket_multipart_form_data). Located in src/routes/upload.rs.

Missing Implementation:

  • Implement magic number-based file type validation within the upload handler in src/routes/upload.rs, after parsing the multipart form data.
  • Implement robust filename sanitization using the sanitize_filename function (or a similar library) within the upload handler.
  • Use rocket_multipart_form_data's per-field limits more comprehensively.

Mitigation Strategy: Secure State Management with Synchronization

Description:

  1. Identify Shared State: Identify all data stored in Rocket's managed state (using rocket::State).
  2. Use Synchronization: If the state is mutable and accessed by multiple requests concurrently, use Mutex or RwLock 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)
    }
  3. 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 in src/routes/counter.rs (accessed via rocket::State).

Missing Implementation:

  • Review src/state.rs to see if any other shared state (accessed via rocket::State) needs synchronization.

Mitigation Strategy: Secure Error Handling with Generic Messages using Rocket's Catchers

Description:

  1. Custom Error Catchers: Implement custom error catchers using Rocket's #[catch] attribute for common HTTP error codes (404, 500, etc.).
  2. Generic Error Messages: In the error catchers, return generic error messages to the user using Rocket's Response and Status types. Do not include any details about the internal error.
    #[catch(404)]
    fn not_found() -> &'static str {
        "Resource not found."
    }
  3. 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 in src/errors.rs.

Missing Implementation:

  • Add unit tests for the custom error catchers using Rocket's testing framework.