Race Conditions
Race conditions (CWE-362) occur when code doesn't properly synchronize access to shared resources, allowing multiple concurrent operations to interfere with each other. The most common variant is Time-of-Check-Time-of-Use (TOCTOU), where a check is performed, then a resource is used, but the resource changes between the check and use.
Real-World Attack Scenarios
Scenario 1: TOCTOU in File Access
A file operation checks ownership then accesses the file:
def delete_file(filename):
# CHECK: Verify user owns file
if not user_owns_file(filename):
raise PermissionDenied()
# TIME WINDOW - Attacker can act here!
# USE: Delete the file
os.remove(filename)The vulnerability:
Between check and use, attacker can modify the file (symlink attack):
Thread 1 (victim):
1. Check: user_owns_file("/home/user/myfile.txt") → True
2. [Context switch]
Thread 2 (attacker):
3. Replace symlink: ln -sf /etc/passwd /home/user/myfile.txt
Thread 1 continues:
4. Use: os.remove("/home/user/myfile.txt")
5. ACTUALLY DELETES: /etc/passwd!The attack:
Result:
Delete system files
Modify critical files
Privilege escalation
System compromise
Finding it: Identify file operations. Try racing with symlinks. Monitor system files for unexpected modifications.
Scenario 2: TOCTOU in Balance Checks
Bank application checks balance before allowing withdrawal:
The vulnerability:
Between check and use, another withdrawal can occur:
The attack:
User has $100
Attacker (or accomplice) makes two simultaneous $100 withdrawals
Both pass balance check
Both execute withdrawal
Account balance is now -$100
Attacker steals money
Result:
Money theft
Account goes negative
Bank loses money
System inconsistency
Finding it: Identify balance check operations. Make simultaneous requests. Check if both succeed.
Scenario 3: TOCTOU in Permission Changes
Admin changes user permissions:
The vulnerability:
Attacker changes their own role between check and promotion:
Result:
Privilege escalation
Attacker becomes admin
Complete system control
Scenario 4: Check-After-Action Race
Application performs action then checks if it should have:
The vulnerability:
Action happens before permission check!
Result:
Users delete accounts they shouldn't have access to
Data loss
System inconsistency
Scenario 5: Inventory Race Condition
E-commerce checks stock before selling:
The vulnerability:
Multiple customers buy simultaneously from limited stock:
Result:
Overselling
Unfulfilled orders
Revenue loss
Customer complaints
Finding it: Purchase items simultaneously. Monitor inventory. Check if overselling possible.
How to Identify Race Conditions During Testing
1. Identify potential race windows
Look for patterns:
Check then use
Check then modify
Multiple step operations
Database operations without transactions
2. Test with concurrent requests
Use threading or multiple processes:
3. Use timing attacks
Deliberately delay operations to increase race window:
4. Monitor for inconsistent state
After concurrent operations, check if state is consistent:
Total balance correct?
Inventory counts correct?
Permissions properly assigned?
5. Use race condition testing tools
Apache JMeter for load testing
Burp Intruder for repeating requests
Custom scripts for precise timing
6. Analyze transaction handling
Check if operations are atomic:
Mitigation Strategies
Use atomic operations
Ensure check and use happen atomically:
Use database transactions
Use locks and synchronization
Use optimistic locking
Add version/timestamp to prevent concurrent modifications:
Avoid symlink attacks
Use secure file handling:
Use file locking
Last updated