GUIDE · SECURITY

Lovable data leak: check your Supabase data

Many Lovable apps return data without login, even with RLS enabled. Check in a few minutes whether your Supabase tables are actually protected.

3 min readLast checked

What the analysis found

Crissy Field and Handelsblatt analysed 159,041 Lovable projects. 34,545 of them used Supabase. On 7,403 of 24,664 sites examined in detail, tables containing email addresses could be read without signing in. The authors note that this is not a confirmed leak rate. It still shows how often access rules are missing or too broad.

Why it happens

Your app talks to Supabase with a public key (anon or publishable key). It sits in the code every browser downloads, which is by design. Row Level Security (RLS) and its policies alone decide who can read which rows. Without RLS, or with a policy that allows everything, anyone with that key can query the table.

The trap: RLS is on and the data is still open

For this guide we built a small Lovable app that shows a contact list without login. Lovable enabled RLS and at the same time created a policy that lets anyone read (using (true) for anon). The table looked protected in the Supabase dashboard and was still readable. Lovable did what we asked: the data was meant to be visible without login. Whether that is intended for your data is your call.

Check it yourself: 1. Find tables without RLS

In the Supabase dashboard, open the SQL Editor:

rowsecurity = false means the table has no access rules.

select tablename, rowsecurity
from pg_tables
where schemaname = 'public';

2. Find policies that allow everyone

Watch for anon or public in roles combined with true in qual or with_check.

select tablename, policyname, roles, cmd, qual, with_check
from pg_policies
where schemaname = 'public';

3. Test from the outside

Your own app only. [] means the table is empty or protected. A record means it is readable without login.

curl "https://YOUR-PROJECT.supabase.co/rest/v1/TABLE?select=*&limit=1" \
  -H "apikey: YOUR_PUBLIC_KEY"

How to fix it: enable RLS

Enable RLS on every table in public:

alter table public.contacts enable row level security;

Replace open policies with a narrower one

Remove open policies and replace them with a narrower one, for example "users only see their own rows" (requires a user_id column):

Prompt for Lovable: "Check all tables for Row Level Security. Only allow signed-in users to read data that should not be public, and only their own rows. Remove policies with using (true) unless the content is meant to be public."

If personal data was exposed, check whether it has already been accessed. Under the GDPR (Art. 33) a personal data breach may have to be reported to the supervisory authority within 72 hours. Get legal advice. This guide is not legal advice.

drop policy "Anyone can read contacts" on public.contacts;
create policy "Read own contacts" on public.contacts
  for select to authenticated
  using ((select auth.uid()) = user_id);

Common mistakes

These mistakes are common:

  • RLS enabled on some tables only, newer tables forgotten.
  • A using (true) policy added for testing and never removed.
  • The service_role key used in the frontend. It bypasses RLS completely (see our guide on the Supabase key).
  • Storage buckets set to public although they hold user files.

Frequently asked questions

Is the public Supabase key in my code a problem?

It is meant to be in the browser. It is only safe with correct RLS. The service_role key never belongs in frontend code.

Is enabling RLS enough?

Only if no policy lets everyone read. Always check pg_policies as well.

How often should I check?

After every new table and after larger changes an AI tool made to your database.

Can LaunchCheck check this?

The free check shows whether your site returns Supabase data without login while loading. In the report, after you confirm your domain, we check which tables your app queries are readable without login. We only count and never store content.

Sources

CHECK YOUR APP

Check your app

The free check loads your app like a visitor and shows what is visible from the outside. You confirm beforehand that you are responsible for the app or authorised to test it.

More guides

All guides →