Mitigation Strategy: Enforce Exhaustive Either
Handling
-
Description:
- Identify
Either
Usage: Perform a codebase search for all instances ofEither
usage (e.g.,Either<ErrorType, SuccessType>
). - Implement
fold
or Pattern Matching: For eachEither
instance:- Option A:
fold
: Replace any direct access to theEither
value with a call tofold
. Thefold
function takes two lambda expressions: one for theLeft
(error) case and one for theRight
(success) case. Ensure both lambdas handle the respective cases appropriately, logging errors, transforming them into user-friendly messages, or returning a safe default value. - Option B: Pattern Matching: Use a Kotlin
when
expression to pattern match on theEither
value. Thewhen
expression should have branches for bothis Either.Left
andis Either.Right
. The compiler will enforce that all cases are handled.
- Option A:
- Automated Checks (Linting): Integrate a static analysis tool (e.g., Detekt, ktlint) into your build process. Configure the tool with custom rules (if necessary) to enforce that all
Either
values are handled usingfold
or pattern matching. This will prevent developers from accidentally introducing unhandledEither
cases in the future. - Code Review: Add a checklist item to code reviews to specifically check for proper
Either
handling.
- Identify
-
Threats Mitigated:
- Unhandled Errors: (Severity: High) - Prevents unhandled exceptions that could lead to crashes or unexpected behavior.
- Information Leaks: (Severity: High) - Prevents sensitive error details from being exposed to users or logged inappropriately.
- Inconsistent Error Handling: (Severity: Medium) - Ensures that errors are handled consistently across the codebase.
-
Impact:
- Unhandled Errors: Risk significantly reduced. Exhaustive handling ensures that all error paths are considered.
- Information Leaks: Risk significantly reduced. Forces developers to explicitly handle error details, making it less likely that sensitive information will be leaked.
- Inconsistent Error Handling: Risk significantly reduced. Promotes a consistent approach to error handling.
-
Currently Implemented:
- Example:
UserService.kt
usesfold
for allEither
results from database operations. - Example:
AuthController.kt
uses pattern matching withwhen
forEither
results from authentication logic. - Example: Detekt is configured with a basic rule to flag direct access to
Either
values (but not enforcingfold
or pattern matching specifically).
- Example:
-
Missing Implementation:
- Example:
PaymentService.kt
has several instances whereEither
results are not handled exhaustively, potentially leading to unhandled errors. - Example: The Detekt configuration needs to be updated with more specific rules to enforce
fold
or pattern matching for allEither
instances. - Example: Code review checklist does not explicitly mention
Either
handling.
- Example:
Mitigation Strategy: Safe Option
Handling
-
Description:
- Identify
Option
Usage: Search the codebase for all uses ofOption
(e.g.,Option<User>
). - Avoid
getOrNull
: Replace any calls togetOrNull
with safer alternatives:fold
: Usefold
to handle bothSome
andNone
cases, providing a lambda for each.getOrElse
: UsegetOrElse
to provide a safe default value if theOption
isNone
. Ensure the default value is appropriate and doesn't introduce any security risks.- Pattern Matching: Use a
when
expression with branches foris Some
andis None
.
- Code Reviews: During code reviews, specifically look for any use of
getOrNull
and ensure thatOption
values are handled safely. - Linting Rules: Configure linting rules to discourage or forbid the use of
getOrNull
.
- Identify
-
Threats Mitigated:
- NullPointerExceptions (or Equivalent): (Severity: High) - Prevents unexpected null pointer exceptions that could lead to crashes or denial-of-service.
- Logic Errors: (Severity: Medium) - Reduces the risk of logic errors caused by assuming a value is present when it might be
None
.
-
Impact:
- NullPointerExceptions: Risk significantly reduced. Eliminates the primary cause of
NullPointerException
s related to optional values. - Logic Errors: Risk reduced. Forces developers to explicitly consider the case where a value might be absent.
- NullPointerExceptions: Risk significantly reduced. Eliminates the primary cause of
-
Currently Implemented:
- Example:
ProductRepository.kt
usesfold
to handleOption<Product>
results. - Example: Code review guidelines discourage the use of
getOrNull
.
- Example:
-
Missing Implementation:
- Example:
AnalyticsService.kt
usesgetOrNull
in several places, potentially leading to null pointer exceptions. - Example: Linting rules are not configured to specifically flag
getOrNull
usage.
- Example:
Mitigation Strategy: Controlled IO
and Side Effects
-
Description:
- Minimize Side Effects: Refactor code to reduce the number of side effects. Push side effects to the boundaries of your system (e.g., interacting with databases, external APIs, file system).
- Explicit
IO
Boundaries: Clearly define whereIO
operations begin and end. UseIO.fx
or similar constructs to createIO
instances, and avoid deeply nestedIO
structures. - Resource Management: Use
IO.bracket
(orResource
in newer Arrow versions) to ensure that resources acquired within anIO
(e.g., file handles, database connections) are properly released, even if an error occurs. This prevents resource leaks.- `IO.bracket(acquire = { ... }, use = { ... }, release = { ... })
- Controlled Execution: Use
IO.unsafeRunSync()
orIO.unsafeRunAsync()
only at well-defined points in your application (e.g., at the entry point of your application or in a dedicated background task). Avoid calling these methods in the middle of business logic. - Auditing: Implement logging or monitoring around
IO
operations. Log the start and end of eachIO
action, along with any relevant parameters or results. This helps to track the execution of side effects and identify any potential issues. - Code Reviews: Review code for proper use of
IO
, ensuring that side effects are managed correctly and that resources are properly released.
-
Threats Mitigated:
- Uncontrolled Side Effects: (Severity: High) - Prevents unexpected behavior caused by uncontrolled side effects.
- Resource Leaks: (Severity: Medium to High) - Prevents resource leaks that could lead to performance degradation or denial-of-service.
- Difficult Debugging: (Severity: Medium) - Makes it easier to debug issues related to side effects.
-
Impact:
- Uncontrolled Side Effects: Risk significantly reduced. Explicit
IO
boundaries and controlled execution make side effects more predictable. - Resource Leaks: Risk significantly reduced.
IO.bracket
ensures that resources are properly released. - Difficult Debugging: Risk reduced. Auditing and clear
IO
boundaries make it easier to track down issues.
- Uncontrolled Side Effects: Risk significantly reduced. Explicit
-
Currently Implemented:
- Example:
DatabaseService.kt
usesIO.bracket
to manage database connections. - Example:
EmailService.kt
usesIO
to encapsulate sending emails.
- Example:
-
Missing Implementation:
- Example:
FileService.kt
does not useIO.bracket
to manage file handles, potentially leading to resource leaks. - Example: Auditing of
IO
operations is not implemented consistently across the codebase. - Example: Some parts of the application use
IO.unsafeRunSync()
in the middle of business logic, making it harder to reason about the code's behavior.
- Example:
Mitigation Strategy: Secure Optics Usage
-
Description:
- Careful Design: When creating lenses or prisms, carefully consider the data they are accessing and modifying. Avoid creating lenses that expose sensitive data unnecessarily. Think about the "least privilege" principle – a lens should only have access to the data it absolutely needs.
- Restricted Access: Control the visibility of lenses and prisms. Use Kotlin's visibility modifiers (e.g.,
private
,internal
,protected
) to limit their scope. Avoid making them public if they only need to be used within a specific class or module. - Validation: If a lens or prism is used to modify data, add validation logic to ensure that the modifications are valid. This could involve checking data types, ranges, or other constraints. This validation should be performed before the modification is applied.
- Code Reviews: During code reviews, pay close attention to the use of optics. Ensure that lenses and prisms are designed securely, that their access is restricted appropriately, and that any modifications are validated.
- Documentation: Document the purpose and usage of each lens and prism, including any security considerations.
-
Threats Mitigated:
- Unintentional Data Exposure: (Severity: High) - Prevents sensitive data from being exposed through improperly designed lenses.
- Data Corruption: (Severity: High) - Prevents invalid data from being written to the data structure through lenses or prisms.
- Unauthorized Modification: (Severity: High) - Prevents unauthorized modification of data by restricting access to lenses and prisms.
-
Impact:
- Unintentional Data Exposure: Risk significantly reduced. Careful design and restricted access minimize the chance of exposing sensitive data.
- Data Corruption: Risk significantly reduced. Validation logic prevents invalid data from being written.
- Unauthorized Modification: Risk significantly reduced. Restricted access limits who can modify the data.
-
Currently Implemented:
- Example: Lenses for accessing user data are marked as
internal
and are only used within theUser
module. - Example: Some lenses have basic validation logic (e.g., checking for null values).
- Example: Lenses for accessing user data are marked as
-
Missing Implementation:
- Example: Some lenses expose more data than necessary, potentially leaking sensitive information.
- Example: Validation logic is not consistently implemented for all lenses and prisms.
- Example: Documentation for optics is incomplete and does not always include security considerations.
- Example: Code reviews do not always thoroughly check the security of optics usage.