Race Conditions


A race condition is a software vulnerability when the resulting outcome from execution processes is directly dependent on the order and timing of certain events, and those events fail to execute in the order and timing intended by the developer.

  • occur when multiple processes (or multiple threads within a process) control or share access to a resource and the correct handling of that resource depends on the proper ordering or timing of transactions.
  • when software logic does not check or enforce the expected order of events,
    • security issues may occur
  • manifest in many ways
    • e.g., time-of-check to time-of-use
  • are difficult to detect and hard to reproduce

Example

If you’re making a $20 withdrawal from your bank account via an ATM, the process might go as follows:

  1. Check the account balance ($100).
  2. Withdraw funds ($20).
  3. Update the account balance (30 withdrawal, you might end up with a bit of a problem.
User 1User 2
- Check the account balance ($100).- Check the account balance ($100).
- Withdraw funds ($20).- Withdraw funds ($30).
- Update the account balance ($80).- Update the account balance ($70).

Because two users share access to the resource, the account ends up recording a balance of 50. The two users “race” to access the resource, and undesirable conditions occur.

Remediation

  • you can generally avoid race conditions by avoiding user access to resources depending on timing

TOCTOU

Time-of-check to time-of-use (TOCTOU) is the potential vulnerability that occurs when there is a change between when an app checked a resource and when the app used the resource.

  • e.g., a multi-threaded banking application used one program thread to check an account balance and another thread to withdraw money
    • if an attacker manipulates the sequence of execution
    • they could potentially overdraw the account
  • highlight importance of atomic operations
    • checking and execution are done as a single, indivisible operation