Skip to content
BuildThenTestedSee packages
CriticalData access

Inverted policy logic

Signed-out visitors or other customers can read rows meant for one account, while the owner sees an empty page and nobody notices. Rules that decide which user can read or change which rows in the database. Check it yourself with the steps below; our test adds what a script and a second account can find.

What it looks like

create policy "owners only" on invoices
  for select using (auth.uid() <> user_id);

-- or, inside a database function:
if auth.role() = 'authenticated' then
  raise exception 'not allowed';
end if;
A row-level security policy (RLS, the database rules that decide which rows each user may see) and a database function whose conditions point the wrong way: they block the owner and let everyone else through.

What happens

Signed-out visitors or other customers can read rows meant for one account, while the owner sees an empty page and nobody notices.

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

One education app built on Lovable had 16 vulnerabilities, 6 critical; a database function denied callers whose role was 'authenticated', so anonymous callers passed and 18,697 user records were readable without login.

  • 16 Vulnerabilities found
  • 6 Critical
  • 18,697 User records exposed
  • 14,928 Unique email addresses
  • 870 Enterprise users with full PII

Feb 2026 · Taimur Khan · all sources

Check it yourself

Uses your builder's dashboard and your browser. No tools to install.

  1. In the Supabase dashboard, open Authentication, then Policies, and read every policy on a table that holds customer data.
  2. Read each condition aloud as a sentence. It should say who is allowed in, such as "the signed-in user's id equals the row's user id". A condition built on "not equal", "is null" or "raise an error when authenticated" is the warning sign.
  3. Sign out of your app completely, then open a page that should show only your own data.
  4. In the dashboard, open Advisors, then Security Advisor, and read every warning about policies and functions.

A bad result is any data appearing while signed out, or a policy whose plain-English reading blocks the owner instead of strangers.

What we check

We call every table and database function three ways: signed out, as a normal account and as a second account, then compare the rows returned with who should see them. The report lists each policy or function where the result is the reverse of its intent.

Fix direction

Rewrite each policy to state who is allowed, comparing auth.uid() with the owner column and adding the TO authenticated clause so anonymous callers stop before the condition runs. Supabase's docs recommend naming the role in every policy and checking that auth.uid() is not null; the Security Advisor flags the most common mistakes.

Mechanism documented in: Row Level Security (verified 2026-09-21); Advisors (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.

Compare packages

Related patterns

Questions

how do i check if my supabase rls policy is backwards

Read the policy condition as a sentence and ask whether it names who is allowed in. A condition that denies signed-in users, or compares the user id with "not equal", lets the wrong people through. Then sign out and open a page that should be private; if data appears, the policy is not doing what you meant.

why can i see data when logged out of my lovable app

The most common reason is a policy or database function whose condition is the wrong way round, so anonymous callers pass and signed-in users are blocked. In one education app built on Lovable, a function raised an error for authenticated callers and returned user records to everyone else; a researcher reported it in early 2026. Lovable's publish flow warns about tables without RLS, and Supabase enables RLS on dashboard-created tables, but neither reads the logic inside a policy, so run the self-check above.

does rls enabled mean my data is protected

Enabling RLS turns the rules on; the rules themselves still have to be right. A table with RLS enabled and one inverted policy exposes as much as a table with no RLS at all. Supabase's Security Advisor flags disabled RLS and always-true policies, and the three-way test in the self-check catches the inverted ones.

Back to the catalogue, or run the self-check for your stack.