# Stealing bitcoin wallet backups from blockchain.info

Missing CSRF token on blockchain.info's Gdrive OAuth callback let an attacker's token be bound to a victim, exfiltrating their wallet backup JSON to the attacker's Drive.

- Payout: $1,600
- Severity: high
- Program: Blockchain.info
- Credited: Shashank
- Disclosed: 2017-11-11
- Write-up quality: 6/10
- Original: http://blog.shashank.co/2017/11/stealing-bitcoin-wallet-backups-from.html
- Library page: https://bugbountylibrary.com/r/blog%3Ablog-shashank-co-2017-11-stealing-bitcoin-wallet-backups-from-html
- Tags: domain:web3 impact:data-leak impact:funds-loss kind:bounty platform:blog sev:high tech:oauth technique:chained vuln:clickjacking vuln:csrf

**Target:** OAuth callback endpoint /wallet/gdrive-update
**Root cause:** The Gdrive OAuth callback accepted an attacker-supplied `code`/token without a CSRF/state token binding it to the victim's session, so the victim's backup was written to the attacker's Drive.
**Steps:**
1. Authenticate own Google account at blockchain.info and complete Gdrive backup authorization.
2. Capture the resulting redirect `https://blockchain.info/wallet/gdrive-update?code={MYGdriveToken}`.
3. Send victim that URL (or frame it) while victim is logged into blockchain.info.
4. Victim's wallet backup JSON is stored into attacker's Google Drive.
**How found:** Inspected OAuth flow requests when clicking the Gdrive/Dropbox backup buttons; noticed the redirect URI carried the token as `code` with no CSRF token, then checked whether the URL was frameable despite site-wide clickjacking protection.
**Exploitation:** Attacker obtains their own Gdrive OAuth token, then lures a logged-in victim to the callback URL inside a sandboxed 1%x1% iframe on a fake lottery page; the victim's wallet backup JSON is written to the attacker's Drive, which can be re-imported at blockchain.info to drain funds.
**Escalation:** Chained clickjacking (frameable callback URL bypassing site-wide frame protection) to force the request with negligible user interaction.
**Insight:** OAuth callback endpoints that store data using the caller's token are CSRF-able if no state parameter binds the token to the session; check whether the callback URL is frameable even when the rest of the site sends X-Frame-Options.
