Access and accounts Required
Check ownership on every record
Before returning or changing a record, check on the server that it belongs to the logged-in user or their team.
How to do it
Look records up with the user in the query, such as WHERE id = $1 AND owner_id = $2. Answer 404 for records the user may not see, so they learn nothing. Random IDs make guessing harder, but they are no defence alone. For APIs, see object authorisation.
Example
GET /api/invoices/2002 HTTP/1.1
Authorization: Bearer <token of user A, who owns invoice 2001>
HTTP/1.1 404 Not Found
How to check
Log in as two test users. With user A's token, request, change and delete user B's records by ID. Try list, export and search routes, IDs inside request bodies and GraphQL queries too. Every request returns 404 or 403, and lists show only A's records.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers security testing playbook: https://agentwranglers.se/playbook/adversarial-testing/access-and-accounts/object-access.