Slide 23 of 28
Part 4 · PreventionSlide 23
Slide 23 · Mitigation 5
MIT 05
Filter at the database level — include the user in every query.

When querying the database for an object, always include the current user's ID as part of the filter — not just the object ID. This way, even if the authorization check in the API code is missed, the database query itself won't return data that doesn't belong to the requesting user.

Vulnerable query: "Get me the order with ID 1041." Returns the order regardless of who owns it.

Safe query: "Get me the order with ID 1041 that also belongs to user 1042." If the order belongs to someone else, the database returns nothing — and the API returns a 404.

Even if a developer forgets the authorization check in the API layer, the database query still enforces ownership. It's defense in depth — two independent layers that both need to fail for a breach to happen.

This only works for direct database queries. APIs that fetch data from third-party services, caches, or file systems need separate ownership checks at those layers too.

// Vulnerable — only filters by object ID SELECT * FROM orders WHERE id = 1041 // Safe — filters by object ID AND owner SELECT * FROM orders WHERE id = 1041 AND user_id = 1042 // Returns nothing if user 1042 doesn't own order 1041
💼 Business takeaway

Ask whether your rate limits apply to data-fetching operations — not just logins. An attacker who can request 10,000 records per minute can enumerate your entire dataset even if each individual request is “allowed.”

← Back Mitigation 6 →