Can users see other users' data? A 10-minute test
By Denys Kharkovskyy · Published · 7 min read
Short answer
Yes, if your database rules are off, too broad, or skipped by server code. Row Level Security (RLS) is the Supabase setting that decides which rows each user can read or change. Test it with two accounts you own: create data as A, look for it as B, then check your RLS rules.
Key takeaways
- Your app's screen can hide another user's data while the database still sends it to their browser.
- The public key in your app is meant to be public. Your database rules (RLS) are the real lock.
- The two-account test checks what your app shows and sends. The rules check covers what the database would hand to anyone who asks it directly.
- Only test your own app, with test accounts and made-up data. If you see a real customer's data, stop.
- If the test fails, fix one table at a time with a narrow prompt, then run both checks again.
Maybe a customer emailed to ask why they can see someone else's invoice. Maybe you just read about an AI-built app that left its users' records open. Either way, the question is the same: can users see other users' data in your app? You can find out in about 10 minutes, with two test accounts and your browser.
This guide uses a Lovable app with a Supabase or Lovable Cloud database as the example. The test itself works on any app you own.
Can users see other users' data in a Lovable app?
They can, and the screen won't tell you. In a Lovable app, what each user can read is decided by Supabase Row Level Security (RLS): the database rules that decide which rows each user can see or change. Apps on Lovable Cloud use the same kind of rules (Lovable docs). If those rules are off, too broad, or skipped by server code, one user's data can reach another user's browser.
Why can this happen when my app looks fine?
Because your app's screen and your database are two separate things.
- The screen filters; the database decides. Your dashboard may only show a user their own orders. But in most Lovable apps, the page gets its data by asking the database directly from the browser, and the database answers whatever its rules allow.
- The key in your app is public on purpose. Supabase's docs say the publishable key (called "anon" in older apps) is safe to expose, because it can only reach what your RLS rules allow (Supabase docs). The secret key (older name: "service_role") skips those rules, so it must never be in the browser.
- So the rules are the lock. For a table with RLS switched off, Supabase's own Security Advisor warns that anyone with your project URL can read, edit and delete all of its data (Supabase docs).
- Server code can walk around the lock. Functions that run on the server with the secret key bypass RLS, so each one has to check who's asking by itself (Lovable docs).
It has happened at scale. In a 2025 check of 1,645 apps featured on Lovable's own showcase, a researcher found that about 1 in 10 (170 apps) let anyone read database tables without logging in, exposing things like emails, phone numbers, payment details and API keys (Matt Palmer, 2025). That's a 2025 finding, not today's rate. The mistake behind it is exactly what the rules check below looks for.
How do I run the two-account test?
Before you start:
- Only test an app you own. Never run this on anyone else's app.
- Use two test accounts with email addresses you own, and made-up data.
- Look, don't destroy. Don't delete anything, and only edit your own test data.
- If you ever see a real customer's data, stop. Note which page showed it and which fields (name, email and so on), but don't copy the values. That's the same rule we follow in our own reviews.
The test:
- Make two accounts, A and B (2 minutes). Sign up twice. Keep A in your normal browser window and B in a private (incognito) window, so both stay logged in.
- Create something private as A (1 minute). An order, a note, a profile detail. Include a marker that's easy to search for, like
TEST-A-PRIVATE. - Open A's link as B (2 minutes). As A, open the item and copy the address from the address bar. Paste it into B's window. Can B see it? Now try changing one word of the marker text as B. If B can save the change, B can edit A's data.
- Check every list as B (1 minute). Dashboard, search, "all items", exports. Does
TEST-A-PRIVATEshow up anywhere? - Check what B's browser received, not just what it shows (2 minutes). In B's window, right-click the page and choose Inspect to open DevTools (the browser's built-in inspector). Go to the Network tab and reload the page. Press Ctrl+F (Cmd+F on a Mac) inside the Network tab and search for
TEST-A-PRIVATE, then for A's email address. This searches everything the page downloaded.
Pass: B never sees anything of A's, on screen or in the Network tab. Fail: any of A's data shows up anywhere, even only in the Network tab. That means the screen is hiding data the database is still sending.
Why does changing the ID in the address matter?
Many apps put an item's ID in the address, like /orders/123 or a long code. If the app loads whatever ID is in the address without checking who owns it, anyone who is sent a link or guesses an ID can open it. Security people call this an IDOR (insecure direct object reference): the app trusts the ID instead of checking the owner.
Step 3 above tests exactly this, safely. Only ever swap in IDs from your own test accounts. Guessing other IDs could open a real customer's record.
How do I check my Supabase RLS rules without writing code?
The two-account test shows what your app sends. The rules show what the database would hand to anyone who asks it directly, without your app's screens in the way. Your app might only ever ask for B's rows; a stranger doesn't have to ask politely. So check both.
As of September 2026, you'll find the rules here: on Lovable Cloud, More → Cloud → Database → RLS policies (Lovable docs); on your own Supabase project, the dashboard → Advisors → Security Advisor (Supabase docs). Look for three things:
- A table with its rules switched off. In Supabase's Security Advisor this shows up as an error named "RLS Disabled in Public" or "Table publicly accessible". If the table holds anything about your users, treat it as urgent.
- A rule that lets everyone through. In Lovable's RLS policies list, check the "Rule expression" column.
truemeans "anyone". That's fine for public content like blog posts, not for orders, messages or profiles. - Rules for people who aren't logged in. The "Applies to" column shows who a rule covers, and
anonmeans visitors who aren't logged in. On private data, that's a red flag.
Lovable's quick check at publish flags the first two for you (Lovable docs). The third needs your judgement, because only you know which tables are meant to be public.
What should I do in the first hour if the test fails?
- Don't send one giant "fix all security" prompt. A vague prompt changes many things at once and can break features that work. Fix one table at a time.
- Lock the table with owner-only rules. Here's the kind of narrow prompt we write for every finding. Paste it into Lovable, changing
ordersanduser_idto your own table and column names:
In the orders table, turn on Row Level Security if it's off. Add rules so a signed-in user can only read, add, change and delete rows where user_id is their own user id. Don't change any other table, page or function. When you're done, list every rule on the orders table.
Supabase notes that once RLS is on, your app can't read or write that table until rules exist (Supabase docs). If a page looks empty for a moment, that's why; it's expected until the rules are in.
- Run both checks again. The two-account test and the rules list. Then re-run Lovable's security scans from More → Security.
- Replace anything secret that was exposed. If an open table stored keys or tokens, or a secret key (service_role or sb_secret_) ever sat in your front-end code, create new ones and switch the old ones off. Supabase's docs walk through rotating a leaked key.
- If real people's data was open, get advice. Under GDPR, a business may have to report a personal data breach to its data protection regulator within 72 hours of finding out (GDPR Art. 33), and sometimes tell the affected users too (Art. 34). This isn't legal advice — check with a lawyer.
What to do next
Do this yourself today:
- Run the two-account test and the rules check above.
- Make them a habit: every time you or your AI tool add a table, run both again.
- Work through the rest of our checklist of 24 common problems in AI-built apps.
When to get help: get a second pair of eyes if your app has teams, roles or shared items (the rules get complicated fast), if the test failed while real users were on the app, or if you're not sure what a rule means. Our free outside-in check looks at what your app shows every visitor, such as keys in your code, and reads your scanner results. The test in this guide needs logins and your permission, so it's part of a full review of your access rules and code, where every finding comes with a fix prompt like the one above.
SELFOIA is not affiliated with Lovable or Supabase.
FAQ
Is it safe that my Supabase key is visible in the browser?
Yes for the publishable key (called anon in older apps): Supabase designed it to be public, and it only reaches what your RLS rules allow. Never for the secret key (service_role in older apps), which skips those rules.
Doesn't Lovable set up these rules for me?
Lovable's docs say it sets up RLS rules automatically when it builds features that store user data, and recommend reviewing them. A rule can still be missing on a new table or broader than you meant, which is why the test checks the result, not just the setting.
Can I run this test on someone else's app?
No. Only test apps you own, with your own test accounts. Opening other people's data in someone else's app can hurt real users.
My app passed. Am I safe?
You've closed one of the most common gaps. Apps with teams, roles, shared items, file uploads or admin pages have more ways to go wrong, and those need a closer look.
Sources
- API keys — Supabase documentation, accessed 2026-09-27
- Advisors — Supabase documentation, accessed 2026-09-27
- Row level security (RLS) policies — Lovable documentation, accessed 2026-09-27
- Security best practices for Lovable apps — Lovable documentation, accessed 2026-09-27
- Security overview — Lovable documentation, accessed 2026-09-27
- Statement on CVE-2025-48757 — Matt Palmer, accessed 2026-09-27
- Art. 33 GDPR: Notification of a personal data breach to the supervisory authority — gdpr-info.eu, accessed 2026-09-27
- Art. 34 GDPR: Communication of a personal data breach to the data subject — gdpr-info.eu, accessed 2026-09-27
Related
Drafted with AI assistance, reviewed and edited by Denys Kharkovskyy.
SELFOIA