# How spending our Saturday hacking earned us 20k

Opaque 'E' token meant to prevent IDOR was reusable across endpoints, letting a username-change token be replayed to read other users' invoice archives.

- Payout: $22,530 (paid EUR 20000)
- Severity: critical
- Program: -
- Credited: Matti Bijnens
- Disclosed: 2019-06-14
- Write-up quality: 8/10
- Original: https://web.archive.org/web/20201028215444/http://incidentsecurity.com/how-spending-our-saturday-hacking-earned-us-20k/
- Library page: https://bugbountylibrary.com/r/blog%3Aweb-archive-org-web-20201028215444-http-incidentsecurity-com-how-spending-our-saturday-hacking-earned-us-20k
- Tags: domain:web impact:data-leak impact:pii-leak kind:bounty platform:blog sev:critical technique:chained technique:recon vuln:access-control vuln:business-logic vuln:idor

**Target:** Web app endpoints /changeUsername, /getInvoice, /getArchive with opaque E token
**Root cause:** The 'E' value is a random string mapped server-side to a cleartext value, but the mapping was not scoped per endpoint/transaction, so a token minted for one field (username) was accepted for another (user ID).
**Steps:**
1. Observe requests carry V (cleartext) and E (opaque token); E is returned in prior responses and only last E accepted.
2. Find a signing oracle: change username to target value, capture returned E for username.
3. Set username to victim invoice ID+1 (12341), copy resulting E into /getInvoice request; error changes from generic to 'Entity does not belong to client', confirming E accepted.
4. For /getArchive, hidden field is user ID; set username to own user ID, copy E into request; trim leading part of ID if 'Could not find client'.
5. Repeat with victim's user ID to retrieve their full bills/earnings archive.
**How found:** Noticed E tokens always returned in prior responses and only last accepted, suggesting timestamped mapping; hypothesized a signing oracle, then searched for endpoints reflecting user-controlled values into E (username), and probed incremental IDs on known endpoints like /getInvoice.
**Exploitation:** Attacker with own account uses username-change endpoint as an oracle to mint E tokens for arbitrary cleartext values, then replays those tokens on IDOR-vulnerable endpoints lacking a second authorization check to read other users' archives and earnings.
**Escalation:** Oracle bug shared with teammates enabled additional IDORs: total earnings lookup by real name and profile picture access, raising combined bounties to €20,000.
**Insight:** When an app uses opaque per-request tokens to stop IDOR, hunt for any endpoint that mints a token for attacker-controlled cleartext (profile fields, usernames) and test replaying it on other endpoints—error-message changes reveal token acceptance even when authorization still blocks.
