Three Invoices, Real Customers: Proof Depth on a Live Fintech API
You are testing a fintech's public REST API in production under an SOW that permits read-only testing with client-supplied test accounts. While checking object-level authorization on GET /v1/invoices/{id}, you request invoice IDs 1001, 1002 and 1003 using a single test account and receive three different customers' invoices. Each response contains full name, postal address, the last four digits of a card, and line items. You stop after three requests.
The client's PSIRT page states that researchers must not access data beyond what is needed to demonstrate a vulnerability, must not store customer data, and must report within 24 hours. Your contract is silent on data handling. The test account belongs to the client and was created for this engagement. The client's critical-fix SLA is 30 days, your report is due in 10 days, and the API has no documented rate limiting.
1. Do you need more requests to prove impact? What will you refuse to do, and why?
Read the worked answer
Three sequential IDs returning three different customers is sufficient proof of broken object-level authorization. The vulnerability is established by the first unauthorized record; the second and third only rule out a coincidence such as a shared account. Additional enumeration adds risk without adding a finding.
Refuse:
- Iterating IDs to count affected records. The count is a database query for their engineering team, not something to derive by harvesting patient or customer data.
- Any write method (PUT, DELETE, POST) against real invoices. A read-only authorization flaw does not require you to modify a customer's billing record to be credible, and deletion is irreversible.
- Fetching attached PDFs or documents 'to see how bad it is'. That is exactly the data minimization the PSIRT page forbids.
- Using a second test account owned by a different customer to 'confirm tenant isolation' without written approval.
One useful addition if permitted: a negative control - the test account requesting its own invoice ID - to show the endpoint behaves normally for authorized objects and that the flaw is authorization, not a misconfigured response. Document the request count and stop condition in the report. If the client wants a blast-radius number, tell them what query to run and ask them to provide the aggregate.
2. What do you do with the three responses and any screenshots, given the contract is silent?
Read the worked answer
Apply the stricter of the two applicable standards - the PSIRT policy - because it is the client's stated expectation and you have no contractual cover for hoarding data.
Immediately:
- Capture evidence in redacted form only: endpoint, request headers minus the token, response status, timestamps, and the field names. Mask names, addresses and card digits in any screenshot.
- Hash the raw captures, then delete the raw response bodies from proxy history and local storage after the hashes and redacted excerpts are recorded. Do not sync them to a personal cloud drive.
- Record the deletion: what was deleted, when, by whom, and the hashes retained. Store that log with the engagement file.
Notify within 24 hours, independent of the report deadline: tell the client what was accessed, which IDs, which fields, when, and that you stopped at three and retained only redacted evidence. They may have their own breach-assessment obligation, and they cannot assess it if they learn in 10 days.
Ask whether they want the unredacted reproduction in the report appendix or only the redacted version; default to redacted when there is no answer. If the SOW is silent, propose a one-paragraph data-handling addendum for the next engagement.
3. Write the key content of the 24-hour notification, and state what you would not include.
Read the worked answer
Include:
- Engagement reference and the exact endpoint and method.
- Timestamps in UTC and the source IP used.
- Invoice IDs requested and the fields returned, by name - name, address, card last four, line items.
- The fact that three requests were made, why you stopped, and that no write operations were attempted.
- Data handling: only redacted excerpts retained; raw bodies deleted at a stated time; hashes recorded.
- Recommended immediate actions: check access logs for that account and source, fix the authorization check to compare the object's owner to the authenticated principal server-side, and review whether sequential IDs are enumerable across other endpoints (
/v1/statements/{id},/v1/users/{id}) - they should look, not you. - A named contact and a request for acknowledgement.
Do not include: unredacted customer data in the email itself, the test account's bearer token, a severity debate, or a demand for a fix timeline. Also avoid speculation about how many records are exposed; you have three data points, and guessing undermines the report. Keep the notification factual and short - the full technical detail belongs in the report, not in an email that may be forwarded widely.