criticalLogins, sessions and access

Row Level Security Disabled

Row-level security is switched off, so any client can read or change every row.

Why it matters

In a Supabase app the browser holds the anon key and queries the database directly. Row-level security is what limits each user to their own rows. Turning it off means any visitor with the anon key, which is in your bundle, can select, update or delete everything in that table. AI tools disable it because it makes a failing query succeed.

What it looks like

This is the shape of code that triggers the rule. AI tools produce it because it works, and nothing tells them it is unsafe.

RLS disabled on a table
alter table public.orders disable row level security;

The smallest fix

minimal patch
-- Turn RLS back on and add the policy the query actually needed:
alter table public.orders enable row level security;

create policy "users read own orders" on public.orders
  for select to authenticated
  using (user_id = auth.uid());

The better fix

If you have a few more minutes, this is the approach that holds up as the app grows.

safe alternative
-- Keep a policy per operation and per role, and nothing for anon unless
-- the data is genuinely public:
create policy "users insert own orders" on public.orders
  for insert to authenticated with check (user_id = auth.uid());

Let your AI tool fix it

When the scanner finds this in your project, it fills in the file and line for you. This is the prompt it gives you to paste into Claude Code, Cursor or whatever you use.

In [the file] at line [the line number], row-level security is disabled or everything is granted to anon: [the flagged code]. Re-enable RLS on the table, remove the grant, and write select/insert/update/delete policies scoped to auth.uid() for the authenticated role. Explain which query needed the change and write the policy that makes it work with RLS on.

How to check the fix worked

1. In Supabase > Table Editor, confirm the table shows RLS enabled.
2. Sign in as user A, then try to select user B's row from the browser
   console with the anon key. It must return nothing.
3. Run the app feature that touched this table; it must still work for
   the row owner.

Further reading