// SECURITY

What is IDOR (broken access control) and does your app have it?

Updated 2026-08-11 · 5 min read

The short answer

IDOR (Insecure Direct Object Reference) is when changing an id in a request lets you read or edit data that is not yours, for example switching /invoice/123 to /invoice/124 and seeing another customer’s invoice. It happens when the server returns records by id without checking that the record belongs to the person asking.

What it is

Broken access control is the number-one risk in the OWASP Top 10. IDOR is its most common everyday form: the app trusts the id in the request and forgets to ask "is this yours?" Because ids are often sequential, an attacker just counts up.

Why it matters to you

One curious user with your app open can walk through every record you have: orders, messages, profiles, uploaded files. No special tools, just editing a number.

How to tell if your app has it

  1. Log in as yourself and open something with an id in the URL or request (an order, a profile, a file).
  2. Change the id to a nearby number.
  3. If you can see someone else’s data, you have IDOR.

How it happens in AI-built apps

AI builders generate endpoints that fetch by id and stop there, because that is enough to "work." On Supabase/Firebase, the same gap appears as a missing ownership check in the row policy, letting any logged-in user read every row.

The fix

Always scope every read and write to the current user on the server.

  • In your API, filter by the authenticated user id, never trust an id from the request alone.
  • In Supabase, use a policy like using ( auth.uid() = user_id ) instead of auth.uid() IS NOT NULL.
  • Prefer non-sequential ids (UUIDs) so records are not guessable, as defense in depth, not the primary fix.

Key takeaways

  • IDOR = the server returns records by id without checking ownership.
  • Test it by changing an id and seeing if you can read someone else’s data.
  • Fix it by scoping every query to the logged-in user on the server.

Frequently asked

Is IDOR the same as missing RLS?

They are closely related. Missing RLS is IDOR at the database layer: any logged-in user can read any row. The fix is the same idea, check ownership, not just "is logged in".

Run a free security scan

Paste your app's link and get a plain-English A–F grade in about 60 seconds, plus the exact fix for every issue.

Free · No signup · Your code stays yours · Results in ~60s