Skip to content

Latest commit

 

History

History
149 lines (118 loc) · 8.82 KB

File metadata and controls

149 lines (118 loc) · 8.82 KB

Mitigation Strategies Analysis for reactivex/rxswift

  • Description:

    1. Training: Ensure all developers understand RxSwift subscriptions and DisposeBag.
    2. Code Style Guide: Mandate DisposeBag use for all subscriptions in the style guide.
    3. Initialization: Create a private let disposeBag = DisposeBag() in every class managing subscriptions.
    4. Subscription Handling: Always use .disposed(by: disposeBag) when creating subscriptions: .subscribe(...).disposed(by: disposeBag).
    5. Lifecycle Management: Tie the disposeBag to the owning object's lifecycle (automatic deallocation usually handles this).
    6. Code Reviews: Check for disposeBag presence, correct usage, and no manual disposal (unless justified).
    7. Static Analysis (Optional): Explore tools to detect potential subscription leaks.
  • Threats Mitigated:

    • Memory Leaks (Severity: High): Unreleased subscriptions prevent garbage collection.
    • Resource Exhaustion (Severity: High): Leaked subscriptions can hold other resources.
    • Unexpected Behavior (Severity: Medium): Leaked subscriptions can react to events after the object is logically gone.
  • Impact:

    • Memory Leaks: Significantly reduced (near elimination with perfect implementation).
    • Resource Exhaustion: Significantly reduced (near elimination with perfect implementation).
    • Unexpected Behavior: Significantly reduced.
  • Currently Implemented: Partially. DisposeBag is used in ViewControllerA, ViewModelB, and NetworkManager.

  • Missing Implementation: DataProcessor class, several utility classes in the Helpers folder.

  • Description:

    1. Identify Error Sources: Find all potential error sources within Observable sequences.
    2. catchError / catchErrorJustReturn: Use these operators in every Observable chain:
      • catchError: Transform the error into a new Observable (e.g., retry, show an error).
      • catchErrorJustReturn: Provide a default value and continue.
    3. Error-Specific Handling: Within catchError, use if let or switch to handle different error types:
      .catchError { error in
          if let networkError = error as? NetworkError {
              // Handle network errors
          } else if let parsingError = error as? ParsingError {
              // Handle parsing errors
          } else {
              // Handle generic errors
          }
          return .empty() // Or a new Observable
      }
    4. retry (with Caution): For transient errors, use retry with a backoff strategy and retry limit.
    5. Global Error Handling (Optional): Use a PublishSubject or BehaviorSubject for unhandled errors (logging, reporting).
    6. Logging: Log all errors (handled and unhandled) with context.
    7. Code Reviews: Verify error handling and type-specific handling.
  • Threats Mitigated:

    • Application Crashes (Severity: High): Unhandled errors can terminate sequences and crash the app.
    • Data Corruption (Severity: Medium-High): Unhandled errors during processing can corrupt data.
    • UI Inconsistencies (Severity: Medium): Unhandled errors can leave the UI in an unexpected state.
    • Denial of Service (DoS) (Severity: Medium): Exploitable repeated failures.
  • Impact:

    • Application Crashes: Significantly reduced.
    • Data Corruption: Significantly reduced.
    • UI Inconsistencies: Significantly reduced.
    • Denial of Service (DoS): Reduced (especially with careful retry logic).
  • Currently Implemented: Partially. Basic error handling in network requests, but not consistent. No global handling.

  • Missing Implementation: Data parsing, user input validation, internal processing. Retry logic inconsistent. No global error subject.

  • Description:

    1. Identify Threading Needs: For each Observable sequence:
      • Where should work be done (background for network, main for UI)?
      • Where should results be delivered (main for UI)?
    2. subscribeOn: Use to specify the thread for subscription and upstream operations: .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background)).
    3. observeOn: Use to specify the thread for downstream operations. For UI: .observeOn(MainScheduler.instance).
    4. Serial Queues: If operations must be sequential, use: SerialDispatchQueueScheduler(qos: .background).
    5. Testing: Thoroughly test concurrent operations.
    6. Code Review: Ensure that all UI operations are happening on Main thread.
  • Threats Mitigated:

    • Race Conditions (Severity: High): Uncontrolled threading leads to unpredictable results.
    • Deadlocks (Severity: High): Threads blocked indefinitely.
    • UI Freezes/Crashes (Severity: High): UI updates from background threads.
  • Impact:

    • Race Conditions: Significantly reduced.
    • Deadlocks: Significantly reduced.
    • UI Freezes/Crashes: Eliminated.
  • Currently Implemented: Partially. observeOn(MainScheduler.instance) used in some UI code, subscribeOn inconsistent.

  • Missing Implementation: Consistent subscribeOn for background tasks. Thorough concurrent testing.

  • Description:

    1. Prefer Observable Creation: Use Observable.create, Observable.just, Observable.from, etc., instead of Subjects.
    2. Use Appropriate Subject Type: If a Subject is required:
      • PublishSubject: Only new events.
      • BehaviorSubject: Latest value and subsequent events.
      • ReplaySubject: Replays past events and subsequent events.
      • AsyncSubject: Only the last value on completion.
    3. Encapsulation: Never expose Subjects directly. Use .asObservable():
      private let mySubject = PublishSubject<Int>()
      var myObservable: Observable<Int> {
          return mySubject.asObservable()
      }
    4. Code Reviews: Scrutinize Subject use; justify necessity and ensure encapsulation.
  • Threats Mitigated:

    • Tight Coupling (Severity: Medium): Overuse creates tight coupling.
    • Unpredictable Data Flow (Severity: Medium): Harder to trace event sources.
    • Code Injection (Severity: Low, but possible): Public Subjects could allow event injection.
  • Impact:

    • Tight Coupling: Reduced.
    • Unpredictable Data Flow: Improved.
    • Code Injection: Risk significantly reduced.
  • Currently Implemented: Partially. Some encapsulation, but others exposed. PublishSubject overused.

  • Missing Implementation: Consistent encapsulation. Review and refactor to reduce Subject usage.

  • Description:

    1. Pure Operators: map, flatMap, filter, scan, etc., should be pure functions – only transform data, no side effects.
    2. do(onNext:) for Side Effects: If unavoidable, use do(onNext:), do(onError:), or do(onCompleted:). This clearly marks side effects.
    3. Isolate Side Effects: Complex or security-sensitive side effects should be in separate functions/classes.
    4. Consider Alternatives: Explore ways to eliminate side effects within operators.
    5. Code Review: Ensure that all side effects are happening inside do operator.
  • Threats Mitigated:

    • Unpredictable Behavior (Severity: Medium): Side effects make code harder to reason about.
    • Race Conditions (Severity: Medium-High): Side effects modifying shared state.
    • Security Vulnerabilities (Severity: Variable): Depends on the side effect.
  • Impact:

    • Unpredictable Behavior: Significantly reduced.
    • Race Conditions: Reduced.
    • Security Vulnerabilities: Reduced.
  • Currently Implemented: Not consistently implemented. Side effects present in some operators.

  • Missing Implementation: Review and refactor to remove side effects or use do(onNext:). Clear guidelines for side effects.