A small SaaS tool I looked at last year had a genuinely nice feature: a button that generated a PDF report of your account's activity, ready to download and share. It worked well, looked polished, and had clearly gotten real design attention. Nobody had thought to ask what happened if you changed one number in the download link.
How the feature actually worked
Clicking the button sent you to a URL that looked something like a report endpoint followed by a numeric ID, report number a few hundred, for example. The server generated a PDF for that specific report and served it back. Straightforward, and it worked correctly for the report you actually clicked on.
What happened when I changed the number
I edited that ID down by one and reloaded the link, still logged in as my own account, still using my own valid session. A different report loaded, someone else's account activity, downloaded as cleanly as my own had been. The endpoint checked that a valid session existed. It never checked whether that session's owner actually had any right to the specific report ID being requested.
Why this is such a common shape of mistake
Building the feature to "generate a report for this ID" is the natural, straightforward way to describe the task, and it's exactly what got built. The step that's easy to leave out is the second half of that sentence: generate a report for this ID, if and only if it actually belongs to whoever is asking. The first version works perfectly in every normal test, because normal testing means clicking your own button and getting your own report. Nobody tests their own feature by trying to guess someone else's ID, because that's not how the feature is meant to be used, which is exactly why it goes unnoticed.
Why export and download features are worth checking specifically
This same shape shows up constantly in anything that generates a file or a document tied to an ID: invoices, reports, exported records, generated certificates. They're a slightly different flavor of the same access-control gap I've written about with regular data views, but they're easy to overlook specifically because a download feels like a small, self-contained action rather than a data-access question with the same stakes as any other page.
The test, and the fix
Generate an export or report as one test account, note the ID in the resulting URL, then try adjacent IDs while still logged in as that same account. Anything that returns real data belonging to someone else is the bug. The fix is the same one that's shown up throughout this blog: every query that fetches a specific record needs to check both the record's ID and the current user's ownership of it, not the ID alone, and a download button is not an exception to that rule just because it feels like a smaller, simpler action than a full page view.