Chapter 2 · Practice 2 of 4
Return the same response for missing and forbidden objects
Why it matters
If /invoices/1043 returns 403 and /invoices/9999 returns 404, an attacker learns which invoice IDs exist, and from that, often how many customers you have and how fast you grow. OWASP's IDOR cheat sheet recommends mapping "missing" and "not allowed" to the same response when existence is sensitive.
Practical rules:
- For objects a user should not know about, return 404 for both cases.
- Use 403 when the user can already see the object but may not perform this action on it (they can view a document but not edit it).
- Keep timing and response size similar too: do not run expensive work only for objects that exist.
Random IDs help, but are not the control. The API Security Top 10 recommends random, unpredictable values for record IDs, and OWASP's IDOR cheat sheet is clear that "even with complex identifiers, access control checks are essential". IDs leak through shared links, logs, browser history, referrer headers and support screenshots. Use UUIDs or similar to slow enumeration, and keep the scoped query.
Avoid
- Returning 403 for objects the user is not supposed to know exist
- Relying on UUIDs alone to keep objects private
- Error messages that name the owner of an object