Skip to content

Latest commit

 

History

History
107 lines (82 loc) · 8.45 KB

File metadata and controls

107 lines (82 loc) · 8.45 KB

Mitigation Strategies Analysis for airbnb/mvrx

Description:

  1. Identify MvRx State: Analyze all classes extending MvRxState and identify fields containing sensitive data.
  2. Encryption Key Management: Use the Android Keystore System for secure key generation and storage (symmetric encryption, e.g., AES). Do not hardcode keys.
  3. Override persistState Handling: The core MvRx-specific step. Instead of directly using the default persistState behavior (which likely uses SharedPreferences or similar), you must intercept the persistence process. This is best done by:
    • Creating a custom base MvRxViewModel class that all your ViewModels inherit from.
    • Overriding the mechanism MvRx uses to persist state. This might involve providing a custom implementation of the persistence logic, or wrapping the existing mechanism. The goal is to inject encryption before the data reaches the underlying storage.
    • Within this overridden mechanism, encrypt sensitive fields before they are passed to the underlying persistence layer (e.g., SharedPreferences).
    • Similarly, decrypt the fields after they are retrieved from the underlying persistence layer, but before they are used to populate the MvRxState.
  4. Key Rotation: Implement a mechanism for key rotation.
  5. Transparent Handling: The encryption/decryption should be transparent to the individual MvRxViewModel implementations. They should interact with the state as usual, without needing to be aware of the encryption.
  • Threats Mitigated:

    • Improper State Persistence and Exposure (Severity: High): Directly addresses the risk of sensitive data in MvRx's persistState being exposed.
    • Unintentional State Exposure via Logging (Severity: Medium): Indirectly mitigates this, as the persisted (and potentially logged) data is encrypted.
  • Impact:

    • Improper State Persistence and Exposure: Reduces risk from High to Low.
    • Unintentional State Exposure via Logging: Reduces risk from Medium to Low.
  • Currently Implemented:

    • Example: A custom base MvRxViewModel (SecureMvRxViewModel) overrides the persistence logic to encrypt/decrypt specific fields annotated with @Sensitive.
  • Missing Implementation:

    • Example: Not all ViewModels inherit from SecureMvRxViewModel.
    • Example: Key rotation is not yet implemented.

Description:

  1. Identify MvRxState Classes: Focus on classes extending MvRxState.
  2. Create toSafeString() in Base Class: Add a toSafeString() method to a custom base MvRxState class (or interface) that all your state classes inherit from. This method should:
    • Return a string representation of the state.
    • Redact or omit sensitive fields.
    • Provide a default implementation that can be overridden by subclasses.
  3. Override toSafeString(): In each specific MvRxState subclass, override toSafeString() to provide a tailored, safe representation of that state.
  4. Integrate with MvRx Logging: The crucial MvRx-specific part. You need to ensure that MvRx's internal logging (when debugMode is enabled) uses your toSafeString() method. This likely requires:
    • Examining the MvRx source code to understand how it logs state.
    • Potentially creating a custom MvRxViewModel base class that overrides the logging behavior.
    • Within the overridden logging, call toSafeString() on the state object before it's passed to the logging framework.
  5. Disable debugMode in Production: Ensure MvRxViewModel.debugMode is always false in production builds.
  • Threats Mitigated:

    • Unintentional State Exposure via Logging (Severity: Medium): Specifically targets MvRx's state logging.
  • Impact:

    • Unintentional State Exposure via Logging: Reduces risk from Medium to Low.
  • Currently Implemented:

    • Example: A base SafeMvRxState interface defines toSafeString().
    • Example: debugMode is disabled in production builds.
  • Missing Implementation:

    • Example: Not all MvRxState classes implement toSafeString() correctly.
    • Example: The custom MvRxViewModel to integrate toSafeString() with MvRx's logging is not yet implemented.

Description:

  1. Code Review (MvRx Focus): Review all classes extending MvRxViewModel, paying specific attention to how the MvRx state is accessed and modified.
  2. Enforce withState: Every read and modification of the state within RxJava streams must use the withState operator. This is a fundamental rule of MvRx.
  3. Enforce setState: Every state update, regardless of whether it's inside an RxJava stream or not, must use the setState method provided by MvRxViewModel. Direct modification of the state object is prohibited.
  4. Training (MvRx Focus): Train developers specifically on the correct usage of withState and setState within the context of MvRx. Emphasize the importance of these methods for thread safety and state consistency.
  5. Static Analysis (Optional): Explore the possibility of using static analysis tools (e.g., custom lint rules) to automatically detect violations of the withState and setState rules.
  • Threats Mitigated:

    • Race Conditions in Async Operations (Severity: Medium): Directly addresses race conditions caused by improper state access within MvRx.
  • Impact:

    • Race Conditions in Async Operations: Reduces risk from Medium to Low.
  • Currently Implemented:

    • Example: Most ViewModels follow the withState and setState rules.
  • Missing Implementation:

    • Example: A recent code review specifically focused on withState and setState has not been conducted.
    • Example: Static analysis rules to enforce these rules are not in place.

Description:

  1. Identify MvRx ViewModels: Focus on classes extending MvRxViewModel.
  2. RxJava Streams within ViewModels: Identify all RxJava streams within these ViewModels. These are the streams that interact with the MvRx state.
  3. onError Handlers (MvRx Context): Implement onError handlers for all RxJava subscriptions within the ViewModels. These handlers must:
    • Log the error (using the sanitized logging approach from the previous strategy).
    • Use setState to update the MvRx state to a safe and consistent state. This is the crucial MvRx-specific part. The error handler must interact with the MvRx state management system.
    • Consider retrying (using retry or retryWhen) if appropriate for the specific operation and state.
  4. onErrorReturn / onErrorResumeNext (MvRx Context): Use these operators to provide default values or fallback streams, and then use setState to update the MvRx state accordingly.
  5. Fail-Safe State Updates: Ensure that even if an error occurs, the MvRx state is transitioned to a well-defined, safe state. Avoid leaving the state in an inconsistent or undefined condition.
  6. Test MvRx Error Scenarios: Write unit tests that specifically target the MvRx ViewModels and simulate error conditions to verify that the error handling logic correctly updates the MvRx state.
  • Threats Mitigated:

    • Unhandled Exceptions in Async Operations (Severity: Medium): Focuses on how unhandled exceptions affect the MvRx state.
  • Impact:

    • Unhandled Exceptions in Async Operations: Reduces risk from Medium to Low.
  • Currently Implemented:

    • Example: Some ViewModels have basic onError handlers that update the state.
  • Missing Implementation:

    • Example: Not all RxJava streams within ViewModels have comprehensive error handling that interacts correctly with setState.
    • Example: Thorough testing of error scenarios specifically within the MvRx context is lacking.