Every Supplier's Documents, One Filename Away
The download endpoint asked which file you wanted — and never checked whether it was yours.
Target anonymized · a retail supplier portal
Supplier and vendor portals are quietly full of sensitive documents — tax forms, contracts, ID scans — uploaded by businesses that assume only they and the buyer can see them. This one had a download endpoint that took a file identifier in the JSON body and returned the file.
The spark
I downloaded one of my own files and looked at the request. The fileId wasn't opaque — it was a readable string, a product-area prefix followed by a long number. Readable IDs are an invitation.
Digging in
Before calling anything an IDOR I run the false-positive gate: send a garbage ID first. A random string came back with an error — good, the endpoint actually looks the file up rather than ignoring the field. Then I took a file ID that clearly wasn't mine and sent it with my own session.
POST /api/file/download HTTP/2
Host: portal.example.com
Content-Type: application/json
{ "fileId": "<another-supplier's-file-id>" }
200 OK, and the response was their document.
Garbage ID → error, someone else's ID → their file. That's the difference between "the server ignores this field" and "the server trusts it completely."
The exploit
Because the identifiers were predictable and there was no rate limiting, this wasn't a one-off peek — it was a scraper. Iterate the numeric portion and you walk out with other suppliers' uploaded documents at scale.
Impact
Cross-tenant disclosure of confidential business documents belonging to other suppliers — exactly the files a portal like this exists to keep private.
The fix
On every file access, check server-side that the authenticated account owns (or is otherwise authorised for) that file. Unguessable references help, but the authorization check is the actual control.
All identifiers, targets and payloads in this post are anonymized or defanged. Findings were reported and resolved through responsible disclosure.