Can someone see another user's data in your AI-built app?
By Seth Tucker · Updated June 2026
Create two test accounts in your app. Log in as the first user, create a record — a note, an order, a profile entry — and note the URL or ID. Log out. Log in as the second user and try to navigate to that first user's record. If you can see it, one of your users can see all of your other users' data. Login does not prevent this automatically. This is the most common authorization failure in AI-built apps.
What this is, in plain English
When someone logs into your app, authentication answers one question: "Who are you?" That is login — the system knows which account is making a request.
A different question is authorization: "What are you allowed to see?" That is the check that prevents one logged-in user from accessing another logged-in user's data.
These are two separate things. An app can have a functioning login screen and still allow any logged-in user to access any other user's records — just by changing an ID number in the URL.
OWASP calls this Broken Object Level Authorization, abbreviated BOLA (also referred to as Insecure Direct Object Reference, or IDOR). OWASP identifies it as one of the most common and most impactful API vulnerabilities. It is also one of the most common failures in AI-generated API code — because the AI generates logic that returns the right data for the normal case without automatically adding the check that blocks returning the wrong data for a variation.
Why AI-built apps are especially prone to this
AI app builders and AI code generators are very good at the happy path: a user logs in, requests their own data, and sees their own data. That path works in testing because the builder is always the only user.
The failure appears when a second user exists and can request the first user's data. The AI did not write that check — not because it cannot, but because no one asked for it explicitly.
Security researchers at RedAccess found more than 5,000 vibe-coded apps with little or no authentication or security controls, with approximately 40 percent exposing sensitive data. The SusVibes benchmark, which tested AI code generation for security, found that the best-performing agent/model combination had a 61 percent functional pass rate but only a 10.5 percent secure pass rate. Object-level authorization is precisely the kind of check that falls into the gap between those two numbers.
The two-account test
This test takes about ten minutes and requires two email addresses (you can use Gmail aliases: [email protected] and [email protected]).
| Step | What to do |
|---|---|
| 1 | Create a test account using your first email address. Log in as this user. |
| 2 | Create a record — a note, a profile entry, an order, a document, whatever your app stores. |
| 3 | Note the URL in your browser's address bar. Look for an ID number in the URL — something like /orders/12345 or /notes/abc-def-123. Copy it. |
| 4 | Log out completely. Create a second test account using your second email address. Log in as this new user. |
| 5 | Paste the URL from Step 3 into your browser's address bar and press Enter. |
| 6 | Check the result. |
If the second user can see the first user's record: your app has a Broken Object Level Authorization vulnerability. It requires a server-side fix — there is no configuration setting or visibility toggle that addresses this. The API endpoint that returns that record needs to verify that the requesting user owns or is permitted to access that record, before it returns the data.
If the second user sees an error, a "not found" message, or nothing: that specific record is protected. Repeat the test for any other resource types your app stores (for example, if you tested with notes, also test with any profiles, orders, settings, or other records your app manages).
If the second user is redirected to their own data: this is also acceptable — the app is redirecting rather than returning the wrong record.
What a fix looks like (for non-technical context)
You do not need to understand how to write the fix, but it helps to know what to ask for.
The fix is a server-side check. When a user requests record number 12345, the server should:
- Identify which user is making the request (from the session or token).
- Look up who owns record
12345. - Compare those two values. If they do not match — and if no explicit sharing or permission grants access — return an error or "not found," not the record.
This check needs to happen on the server, every time, for every endpoint that returns or modifies user-specific data. A check that only happens in the browser can be bypassed by anyone who knows how to make a direct request to the API.
If your app has rows in a Supabase database, this check can be enforced at the database layer using Row Level Security policies. See How to tell if your Supabase database is exposed for the full Supabase walkthrough.
The "change the ID in the URL" test is not the only version of this
The URL is the most obvious place to check, but it is not the only one. The same vulnerability can exist in:
- Request body parameters: a form submission or API call that includes a record ID in the JSON body, where changing that ID returns a different user's data.
- Query string parameters:
?invoice_id=99in a URL where the backend does not verify ownership of invoice 99. - File download endpoints:
/download?file=user-abc/private-document.pdfwhere the path is guessable or enumerable. - Search or filter endpoints: queries that accept a user ID as a filter parameter without verifying that the requesting user can filter by that ID.
Testing the visible URL is the first check. If it passes, also consider whether your app has any of these other patterns and test them the same way.
What to ask an expert
This is one of the areas where a developer or security reviewer can add the most value in a short conversation, because the fix requires code changes that need to be applied consistently across every relevant endpoint. Questions worth bringing:
- For each type of record my app stores, is ownership verified server-side before the record is returned?
- Are there any endpoints in my app that accept a record ID as a parameter without checking ownership?
- Does my Supabase RLS configuration enforce this check at the database layer, or does it depend entirely on application-level checks?
- What about shared or team-accessible records — does the ownership check correctly handle legitimate multi-user access while still blocking unauthorized access?
If you want AgentC to run the two-account test on your app and review the server-side authorization logic, the right starting point is a demo conversation. We test what is actually there, not what the code intends.
Related guides in this series
- Is your AI-built app safe to put in front of customers? (the pillar guide) — full triage across all security areas
- The pre-launch security checklist for Lovable, Replit, Bolt, and Base44
- How to tell if your Supabase database is exposed (without being a developer)
- Production-ready vs demo-good: the vibe-coding reality check
- You already shipped and now you are worried: a 60-minute containment plan
Frequently asked questions
My app has login. Does that mean users cannot see each other's data?
Not automatically. Login answers "who are you?" — it authenticates the request. Whether one user can access another user's records is a separate check called object-level authorization, and it must be implemented explicitly at the API or database layer. The presence of a login screen does not prevent a logged-in user from accessing another user's data by changing an ID in a URL or request. Run the two-account test described above to find out whether your app enforces this correctly.
What is BOLA / IDOR?
Broken Object Level Authorization (BOLA), also called Insecure Direct Object Reference (IDOR), is the vulnerability that occurs when an app returns a resource to a user without verifying that the user is permitted to access that resource. In practice: a user requests /orders/12345, the app returns the order, but does not check whether the logged-in user owns order 12345. OWASP consistently ranks this as one of the most common and impactful API vulnerabilities.
The second user got a "404 not found." Does that mean the data is protected?
A 404 response is generally good — it means the app did not return the data. However, a 404 response can also indicate that the check is happening incorrectly (for example, the app returns 404 whether the record does not exist or whether the user does not own it). For a thorough test, verify that the error is consistent: if you create a record with the second user and then request the first user's record ID, both should return 404 for the second user, not just the ones that do not exist.
What if my app uses Supabase?
Supabase Row Level Security can enforce object-level authorization at the database layer. If RLS is enabled and your policies correctly reference the authenticated user's ID (using auth.uid()), a request for another user's row will return nothing — the database enforces the check before the data reaches the API layer. If RLS is disabled or policies do not reference user identity, Supabase will return whatever the query asks for. The two-account test verifies the actual behavior regardless of what the configuration claims.
Can the AI fix this if I describe the problem?
AI app builders and AI code generators can add object-level authorization checks when prompted to do so — but generating the fix and verifying that it was applied correctly everywhere are two different things. A fix that is applied to one endpoint but not another leaves the app partially vulnerable. Verification — re-running the two-account test across all resource types after the fix — is what confirms the problem is actually resolved.
About this guide
Written by Seth Tucker, founder of AgentC Consulting. Seth spent approximately five years as a security engineer on election infrastructure used by roughly one in three American voters, holds SOC 2 Type 2 and ISO 27001 experience, and now helps non-technical founders and operators build, review, and trust AI-built applications.
Last updated: June 2026. Sources cited throughout reference original research, vendor documentation, and public reporting.
More than vibes
Want a second set of eyes on your app?
The right starting point is a demo conversation, not a form. We look at what you built, ask the questions that matter for your situation, and tell you plainly what is safe to ship and what needs work first.