Any signed-in user can read every row
What it looks like
create policy "Authenticated users can view orders"
on public.orders
for select
to authenticated
using (auth.role() = 'authenticated');What happens
Anyone who creates a free account can page through every other customer's records, which is a data breach with a sign-up form as the only step.
Where it shows up
Descriptive, not a verdict: builders and stacks whose defaults make this reachable, or that a public incident names. Each hub states the tool's own security features.
Seen in public
A scan of 1,645 Lovable-built apps found 170 (about 10.3%) with database endpoints readable without login because Supabase row-level security policies were missing or too broad; recorded as CVE-2025-48757, CVSS 9.3.
- 1,645 Apps scanned
- 170 Apps with inadequate RLS
- 10.3% Share of scanned apps
- 303 Exposed endpoints
- 9.3 Critical CVSS 3.1 base score (CVE record)
- 8.26 Researcher's own CVSS base score
- 2025-03-21 Scan date
- 2025-05-29 Public disclosure
May 2025 · Matt Palmer (Replit, Inc.) · all sources
Check it yourself
Uses your builder's dashboard and your browser. No tools to install.
- In the Supabase dashboard open Authentication, then Policies. Row Level Security (RLS) is the per-row access rule set Postgres applies to each query, and this page shows each policy's expression.
- For each table holding private data, read the USING expression. Look for
auth.role() = 'authenticated',auth.uid() is not nullortruewith no reference to a column such asuser_idorowner_id. - Create two test accounts in your live app. Sign in as the first, create a record, sign out, sign in as the second, and try to open the first account's record through the app or by changing the id in the address bar.
- A bad result is a policy that checks only for a login, or a second account that can see the first account's record.
What we check
We sign in as several unrelated test users, enumerate every table and storage bucket each can list, and compare the results across accounts to find rows that belong to someone else. The report shows the table, the policy text and the cross-account rows reached, with personal data redacted.
Fix direction
Add an ownership condition to each policy, such as auth.uid() = user_id, or a membership check through a team table for shared data. Keep a login-only policy only for content every customer is meant to see. Supabase's Security Advisor and the two-account test above catch regressions after each change.
Mechanism documented in: Row Level Security (verified 2026-09-21); Avoid insecure rules (verified 2026-09-21).
Covered by
Pre-launch check ($490, 48 hours) and Security sweep ($290, 24 hours)
Both include a re-check after your fixes.
Related patterns
- RLS policy that allows everything with using (true)Data accessCritical
The table looks protected in the dashboard, yet any visitor with the public anon key can read, insert, update and delete every row.
- Row Level Security disabled on a tableData accessCritical
Anyone with the project URL and the public anon key, both of which sit in the app's JavaScript, can read, edit or delete every row in the table.
- Record ids accepted without an ownership checkData accessCritical
Anyone who changes the id in a URL or request can read, edit or delete another customer's record.
- Inverted policy logicData accessCritical
Signed-out visitors or other customers can read rows meant for one account, while the owner sees an empty page and nobody notices.
Questions
supabase rls policy for authenticated users only is that enough
Only for data every customer is allowed to see. A policy that checks auth.role() = 'authenticated' confirms the caller has an account and nothing more, so every account reads every row. For per-customer data, the expression needs to compare a column on the row, such as user_id, with auth.uid().
how do i test if users can see each other's data
Create two test accounts in your live app. Add a record with the first, then sign in as the second and try to open that record through the app and by editing the id in the address bar. Also check the Network tab in the browser's developer tools for list requests that return more rows than the second account created. Any cross-account view is a finding.
firebase rule allow if request auth is not null
Firebase's own documentation lists a rule that only checks request.auth != null under rules to avoid unless you have confirmed that every logged-in user should have access to that data. For private data, compare request.auth.uid with an owner field on the document. Firebase's emulator lets you test the rule with different users before deploying.
Back to the catalogue, or run the self-check for your stack.