Penetration test report
Example finding
Any signed-in user can read any customer’s invoices
Severity: High
An ordinary customer changes an invoice ID and reads another customer’s invoice.
Read the full findingHide the full finding
- Weakness
- CWE-639
- CVSS 4.0
- AV:N/
AC:L/ AT:N/ PR:L/ UI:N/ VC:H/ VI:N/ VA:N/ SC:N/ SI:N/ SA:N - Found in
- Test with accounts (2.3)
- Status
- Proven
Proof
- 1We are signed in as user 1042, an ordinary customer.
- 2We ask for invoice 88213 by changing one number in the URL.
- 3The server returns it. It belongs to customer 2291, with their name and bank details.
GET /api/v2/invoices/88213 HTTP/2Host: app.example-saas.comCookie: session=7f3a…c91eAccept: application/jsonHTTP/2 200 OKContent-Type: application/json { "invoice_id": 88213, "customer_id": 2291, "customer_name": " ", "iban": "FR76 0189", "amount_due": 18400.00}Remediation
- Enforce object-level authorization on the server. Load the invoice, then compare its account ID with the account in the caller’s session before returning any data.
- Return 404 Not Found when the check fails, so the response does not confirm that the invoice exists.
- Put the check in one shared layer (middleware or data access) and apply it to every endpoint that takes an object ID, not route by route.
- Add a regression test that requests another account’s invoice and expects 404.
- Search access logs for invoice requests outside the caller’s account to find out whether the flaw was used before the fix.
Random IDs such as UUIDs make the flaw harder to find. They do not fix it.
Retest
Request invoice 88213 as user 1042. Expected result: 404, no invoice data.
References
OWASP Top 10:2025, A01 Broken Access Control. OWASP ASVS 5.0, requirement 8.2.2.