Why can one user see another user's data?

By Aakshar Garg, Founder, Fixier · Last reviewed

the short answer

Because something is fetching records by id without checking who is asking. Logging in proves who someone is; it does not decide what they are allowed to open. That second check — a rule in the database, or an ownership check on the id in the URL — is the piece that gets skipped when an app is built quickly.

If you are here because a customer just emailed you a screenshot of someone else's data, do two things in this order: work out how far it reaches, then stop it. Do not start by rewriting code. The checks below take a few minutes each and tell you which of the six causes you actually have — and the fix is different for each one. This is a category of bug, not a mistake unique to you: broken access control is A01, the top entry in the OWASP Top 10 for 2025.

The six things that cause it

In the order we check them. Each one is invisible while the app appears to work perfectly, which is why they survive to launch.

What breaksWhat you'd notice
No access rules on the table at allcriticalThe database was never told to restrict anything, so it answers every request it receives. Anyone who can reach your app can ask for any row and get it.
A rule that allows everyonecriticalA rule exists — so dashboards and scanners look green — but it was written as "allow anyone signed in" during development and never tightened to "allow the person who owns this row".
No ownership check on the id in the URLcriticalChanging /invoices/1042 to /invoices/1043 loads somebody else's invoice. The login worked. Nothing compared that record to the person asking for it. Engineers call this an IDOR.
Rules on reading but not on writinghighPeople can only see their own records, but can still edit or delete records they were never allowed to see. The leak goes the other way and is usually found much later.
A privileged key reachable from the browsercriticalOne key in the front end skips every rule you wrote, however carefully you wrote them. The rules are fine; nothing is enforcing them.
A report, export or view that skips the ruleshighThe table is protected but the CSV export, admin screen or summary view reads around it — so the data leaks through the one path nobody thought to check.

Is this a data breach?

If someone who should not have been able to see personal data was able to see it, then yes — treat it as one until you have evidence otherwise. It counts whether or not anyone acted maliciously, and whether or not the person who found it was a customer being helpful. Intent is not part of the definition.

The distinction that matters for what you do next is exposure versus access. Exposure means it was possible. Access means it happened. Your logs decide which one you have, which is why the first move is to look rather than to patch — patching first can destroy the evidence that would have told you the scope.

How do I check whether this is happening in my app right now?

Sign up two accounts in two different browsers. Create something in the first account — an order, a document, a project — and note the id in the URL. Then, signed in as the second account, put that id in the URL and press enter. If you can see it, you have reproduced the problem, and you did not need any tools to do it.

Then repeat it for the other three actions, because they fail separately: try to edit it, try to delete it, and try to include it in any export or report. It is completely normal to find that reading is properly locked down and deleting is not.

Do this test signed in as a real second user, through your app, exactly as a customer would. Testing from your database dashboard or with an admin key proves nothing — those bypass the rules by design and will make a broken app look fine.

Why do AI-built apps get this wrong so often?

Because nobody asks for it. You asked for a dashboard that shows a customer their orders, and you got one. You did not ask for "and make it impossible for a different customer to open this page" — and an AI builder will not invent a requirement you never stated. The feature is what gets specified; the restriction is what gets assumed.

It is worth being clear that this is not a defect in the tool, and it is not carelessness on your part. It is a gap in the request. Working software and safe software are two different specifications, and only one of them is visible when you click around your own app as its owner.

Do I have to tell my customers?

Often yes, and the obligation is usually faster than people expect. Under GDPR you must notify your supervisory authority without undue delay and, where feasible, within 72 hours of becoming aware — unless the breach is unlikely to result in a risk to people's rights and freedoms. Under India's DPDP Act you must intimate both the Data Protection Board and every affected person, with no minimum size threshold.

India's rules are specific about sequence: tell affected people without delay through their account or a registered contact method, give the Board an immediate description of the breach, and follow it with a fuller report within 72 hours.

This is a summary of published law to help you understand the shape of the obligation — it is not legal advice, and which regime applies depends on where your users are, not where you are. If real personal data was reachable, talk to a lawyer the same day.

It only happened to one user — is that still serious?

Almost always, yes, because one user seeing one record is rarely the actual scope. The same missing check usually applies to every record in that table — what varies is only who happened to try. Assume the ceiling is "every row" until your logs show otherwise.

The reasoning that gets people into trouble here is treating the one report as the scope. The customer who wrote in found it by accident, which tells you it was easy to find, not that it was rare.

Can I fix this myself?

The ownership check usually yes — comparing the signed-in person against the owner of the record is a small, well-documented change with a clear finish line. Database access rules are the ones worth getting help with, because they fail silently in both directions: too loose and everything leaks, too tight and your app quietly shows empty pages.

Whatever you do, do not fix it by turning the rules off to make the app work again. That converts a scoped problem into a total one. If your app goes blank after you enable protection, that is the safe failure — it means the rules are on and the policy you meant to write is missing.

Tool-specific detail: Lovable, Bolt.new, v0. If your data is in Supabase, the Supabase RLS checklist is the mechanism in full.

How do I stop it coming back?

Make the two-account test part of shipping rather than a thing you did once. Every time you add a table or a page that shows somebody their own records, create the second account and try to reach the first account's data. It takes about two minutes and it is the only check that tests the thing you actually care about.

The durable version is to make the rule live in the database rather than in each screen. Rules written per-page have to be remembered every time anyone adds a page; a rule in the database applies to screens that do not exist yet. This is the second of the seven layers.

The seven-layer production check

Every audit we run walks the same seven layers, in this order. Each one is a question you can answer about your own app today — no tooling required.

  1. 1

    AccessCan a stranger reach something they shouldn't?

    authentication, session handling, ownership checks on every route

  2. 2

    TenancyCan one customer see another customer's data?

    row-level security, tenant scoping, IDOR on every id in a URL

  3. 3

    SecretsWhat's shipped in the browser that shouldn't be?

    keys in the client bundle, service-role credentials, token scope

  4. 4

    Money pathsCan a customer be charged twice — or not at all?

    idempotency, webhook retries, payment state reconciliation

  5. 5

    Load and costWhat happens at a hundred times this traffic, and what's the bill?

    N+1 queries, missing indexes, unbounded jobs, runaway spend

  6. 6

    ObservabilityWould you know it broke before a customer told you?

    error tracking, structured logs, alerting on the paths that matter

  7. 7

    RecoveryIf the data went wrong today, could you get it back?

    backups you've actually restored, reversible migrations, rollback

Each layer in full — what it means, how to test it yourself, and the fix: the seven-layer production check.

Sources

Every claim above about a third-party tool was checked against that tool's own documentation on July 27, 2026. These products change fast — if you spot something out of date, tell us.

Related guides

Want someone to actually check?

We audit AI-built apps against all seven layers and hand back a report in plain English — with the technical detail underneath for whoever fixes it. Startup-friendly pricing, scoped to your project.

Book an Audit