# Delete Credit Cards from any Twitter Account in ads.twitter.com [New Vulnerability]

Missing authorization on ads.twitter.com payment_methods/handle_failed lets any logged-in user delete another account's credit card by guessing a 6-digit id.

- Payout: hidden
- Severity: high
- Program: X / xAI
- Found by: secgeek
- Disclosed: 2014-09-30
- Write-up quality: 6/10
- Original: https://hackerone.com/reports/27404
- Library page: https://bugbountylibrary.com/r/h1%3A27404
- Tags: area:web domain:web impact:dos impact:integrity kind:bounty platform:hackerone sev:high tech:rest vuln:access-control vuln:business-logic vuln:idor

**Target:** ads.twitter.com payment_methods/handle_failed endpoint
**Root cause:** The dismiss/handle_failed POST endpoint authorizes only by the 6-digit credit card id in the URL and body, without verifying the card belongs to the requesting account.
**Steps:**
1. Log in to ads.twitter.com and create a campaign with an invalid credit card.
2. Wait for the card to reach failed/pending status (~48h).
3. Open /accounts/[account id]/payment_methods and click Dismiss while intercepting the request.
4. Observe `POST /accounts/18ce53wqoxd/payment_methods/handle_failed/220152` with body `utf8=...&authenticity_token=...&id=219642&dismiss=Dismiss`.
5. From a second account/browser, inspect the radio button of a valid card to read its 6-digit id.
6. Replay the saved request replacing the id in both POST body and URL with the victim's card id; the card is removed.
**How found:** Researcher noticed the Dismiss action keyed only on a short numeric card id and tested cross-account replay, similar to a prior report (#27205) but with lower precondition (no account id needed).
**Exploitation:** Attacker logs in with any account, captures their own dismiss request, then replays it with a victim's 6-digit card id in the URL and POST body. No ownership check, so the victim's card is deleted without interaction. Ids are only 6 digits, enabling brute-force/mass deletion.
**Escalation:** Mass brute-force of 6-digit ids to delete all cards across accounts and halt campaigns.
**Insight:** State-changing actions keyed on short sequential numeric ids (6 digits) with no ownership check are both IDOR and brute-forceable; test replaying your own captured request with another user's object id in both URL and body.

