1 What are Race Conditions?
A race condition occurs when the outcome of a program depends on the relative timing of two or more concurrent operations. In security contexts, an attacker deliberately triggers a window between a check and the subsequent action to gain an unintended advantage.
Consider a bank transfer endpoint that checks the balance then deducts it:
def transfer(user_id, amount):
balance = db.get_balance(user_id) # READ
if balance >= amount:
db.set_balance(user_id, balance - amount) # WRITE
send_money(amount)
If two requests arrive simultaneously, both may read the same balance value (e.g. $100), both pass the check, and both deduct $80 — leaving the account at -$60. This is called a double-spend vulnerability.
Real-world impact: Race conditions have been exploited to overdraw bank accounts, redeem the same coupon multiple times, claim bonus credits repeatedly, and bypass rate limits.