# Bypassing 2FA for BTC transfers

Internal wallet transfer endpoint skipped 2FA and accepted any wallet ID, letting an attacker with account access move BTC to an external wallet without a 2FA code.

- Payout: $1,000
- Severity: high
- Program: Coinbase
- Credited: michiel
- Disclosed: 2014-09-25
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/10554
- Library page: https://bugbountylibrary.com/r/h1%3A10554
- Tags: domain:web impact:funds-loss kind:bounty platform:hackerone sev:high tech:rest vuln:auth-bypass vuln:business-logic vuln:mfa-bypass

**Target:** POST /accounts/transfer_money internal transfer endpoint
**Root cause:** The internal transfer handler trusted the client-supplied transaction[to] wallet ID and did not enforce the 2FA requirement that applies to external sends, since it assumed the destination was always an account-owned wallet.
**Steps:**
1. Enable 2FA requirement for sending any amount of BTC.
2. Create a second wallet and open https://coinbase.com/accounts.
3. Click Transfer, select source wallet, pick destination and amount, intercept the POST /accounts/transfer_money request in Burp.
4. Replace `transaction[to]` with the Mongo BSON ID of an external attacker-controlled wallet (harvested from DOM `data-wallet-id`).
5. Forward request; funds move with no 2FA prompt.
**How found:** Researcher noticed the internal transfer feature was only visually gated on having two wallets, hypothesized the 2FA check was tied to the external-send flow rather than the transfer endpoint, and tested by tampering with the destination wallet ID.
**Exploitation:** Attacker with a hijacked session initiates an internal transfer, swaps the destination wallet ID for their own external Coinbase wallet ID, and submits; the server processes it as an internal transfer and moves BTC without requiring a 2FA code.
**Insight:** When a feature is only shown conditionally in the UI (e.g. transfer requires two wallets), the backend often lacks the same precondition; also test whether 2FA enforcement is bound to the endpoint or to the destination-wallet ownership check.
