# Race conditions on the web

Race conditions in Facebook email confirmation, Cobalt Bitcoin withdrawal, MEGA purchases and Keybase invites let attackers duplicate single-use actions.

- Payout: unconfirmed
- Severity: medium
- Program: Cobalt.io, Meta / Facebook, MEGA, Keybase
- Credited: Josip Franjkovic
- Disclosed: 2016-07-12
- Write-up quality: 7/10
- Original: https://www.josipfranjkovic.com/blog/race-conditions-on-web
- Library page: https://bugbountylibrary.com/r/blog%3Ajosipfranjkovic-com-blog-race-conditions-on-web
- Tags: domain:web impact:ato impact:funds-loss impact:integrity kind:bounty platform:blog sev:medium tech:rest technique:race-window vuln:business-logic vuln:race-condition

**Target:** Web registration, withdrawal, coupon and invite endpoints
**Root cause:** Check-then-act logic on single-use resources (email confirmation codes, coupon redemption, invite limits, balance debits) without atomic locking, so concurrent requests all pass the check before state is written.
**Steps:**
1. Facebook email: register account without confirming email/phone, obtain access_token
2. Fire concurrent requests to `api.facebook.com/method/user.editregistrationcontactpoint` alternating `add_contactpoint` between your email and victim email
3. Confirmation link sent to your email contains `c=<your code>&code=<victim code>`; use victim code to confirm their email
4. Cobalt: send concurrent Bitcoin withdrawal requests to withdraw one bounty multiple times
5. MEGA: send concurrent `eu.api.mega.co.nz/cs` purchase requests to buy premium repeatedly, driving balance negative
6. Keybase: send many concurrent POSTs with different `email` values to invite endpoint to exceed invite limit
**How found:** Accidentally confirmed a random email during mobile registration testing (~5000 requests), then re-tested to build a reliable PoC; separately applied the same concurrent-request pattern to withdrawal, coupon and invite flows.
**Exploitation:** Attacker parallelizes requests so multiple threads read the same pre-state (unconfirmed email, unused coupon, single invite, sufficient balance) and each commits, duplicating the effect: confirming an email they don't own, redeeming multiple coupons, buying premium repeatedly on negative balance, or minting extra invites.
**Escalation:** Chained email-confirmation race to account/identity control; coupon race scaled to multiple redemptions per account.
**Insight:** Single-use state transitions (email verification, coupon redemption, invite quotas, balance debits) are prime race targets: look for endpoints where a check and a write are separate, and fire the same request in parallel with alternating parameters to catch cross-request state bleed like a code from one email validating another.
