Key Takeaways

  • Race conditions occur when operations that should be atomic aren't.
  • TOCTOU (Time-of-Check to Time-of-Use) is the classic pattern.
  • Common in: coupon redemption, file operations, banking.
  • Fix with database locks, atomic operations, or mutex.

Race conditions are timing-dependent bugs where the outcome depends on the sequence of events. In security, they often allow bypassing limits, double-spending, or privilege escalation.

The TOCTOU Pattern

// VULNERABLE CODE
async function redeemCoupon(userId, couponCode) {
  // CHECK: Is coupon valid and unused?
  const coupon = await db.query(
    'SELECT * FROM coupons WHERE code = ? AND used = false',
    [couponCode]
  );
  
  if (!coupon) throw new Error('Invalid coupon');
  
  // GAP: Attacker sends many requests here!
  
  // USE: Mark as used and apply discount
  await db.query('UPDATE coupons SET used = true WHERE code = ?', [couponCode]);
  await applyDiscount(userId, coupon.value);
}

If an attacker sends 100 concurrent requests, all 100 might pass the CHECK before any executes USE!

Exploitation Techniques

# Send 100 concurrent requests using Turbo Intruder (Burp)
def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                           concurrentConnections=100,
                           requestsPerConnection=1)
    for i in range(100):
        engine.queue(target.req)

# Or with Python
import asyncio, aiohttp

async def exploit():
    async with aiohttp.ClientSession() as session:
        tasks = [session.post('/redeem', data={'code': 'DISCOUNT50'}) 
                 for _ in range(100)]
        await asyncio.gather(*tasks)

Real-World Examples

Prevention: Atomic Operations

// SECURE: Atomic update with condition
const result = await db.query(`
  UPDATE coupons 
  SET used = true 
  WHERE code = ? AND used = false
  RETURNING *
`, [couponCode]);

if (result.rowCount === 0) {
  throw new Error('Coupon already used');
}

// Only one request can succeed!

Frequently Asked Questions

How do I test for race conditions?
Use Burp Suite's Turbo Intruder with race.py, Python asyncio with many concurrent requests, or specialized tools like RaceTheWeb.

Master advanced web attacks.
Business Logic Flaws