# How I Hacked Instagram Again

Instagram bound password-reset codes to a reusable device_id, so one device could request codes for many accounts and brute-force the 6-digit space within the 10-minute window.

- Payout: $10,000
- Severity: high
- Program: Meta / Facebook
- Credited: Laxman Muthiyah
- Disclosed: 2019-08-26
- Write-up quality: 6/10
- Original: https://thezerohack.com/hack-instagram-again
- Library page: https://bugbountylibrary.com/r/blog%3Athezerohack-com-hack-instagram-again
- Tags: domain:api impact:ato kind:bounty platform:blog sev:high tech:rest technique:race-window vuln:account-takeover vuln:auth-bypass vuln:business-logic

**Target:** Instagram account recovery API (i.instagram.com /api/v1/accounts/account_recovery_code_verify/)
**Root cause:** The recovery code is validated only against the device_id that requested it, and a single device_id can request codes for unlimited accounts, so one device holds many valid codes simultaneously.
**Steps:**
1. Request password reset codes for many victim accounts using the same `device_id` via the recovery request endpoint.
2. Note codes are 6 digits (000001-999999) and expire in 10 minutes.
3. For each target account, POST `recover_code=NNNNNN&device_id=<same-id>` to `/api/v1/accounts/account_recovery_code_verify/` incrementing the code.
4. With 1M accounts requested, the full code space is covered and every account is takeover-able within the 10-minute window.
**How found:** Prior research showed device_id validates reset codes; the author hypothesized the same device_id could be reused across multiple accounts' reset requests, then tested and confirmed it.
**Exploitation:** Attacker requests reset codes for a large batch of accounts sharing one device_id, then brute-forces the 6-digit code per account against the verify endpoint before the 10-minute expiry; success rate scales with number of accounts requested (100k accounts ≈ 10%).
**Escalation:** Scaling the number of requested accounts raises success probability linearly up to 100% at 1M accounts.
**Insight:** When a reset/OTP code is bound to a client-supplied identifier (device_id) rather than the account, check whether that identifier can be reused across many accounts to multiply the number of simultaneously valid codes and shrink the brute-force space per account.
