Is my Lovable app secure? A 10-minute self-check
· 7 min read · By the Rowlock team
Short answer
It can be, but you should check. If your app uses Supabase, its safety depends mostly on Row Level Security policies, and AI builders sometimes generate rules that are too open. The seven checks below take about ten minutes, need no coding, and tell you whether a stranger could read or change your users’ data.
Lovable and similar builders (Bolt, Replit, v0) connect your app to a Supabase database and let the browser talk to it directly. That only works safely when the database itself enforces who can see what. You don’t need to read the generated code: everything below happens in your Supabase dashboard. Have it open on your project.
1Open the Security Advisor (1 minute)
In Supabase, go to Advisors → Security Advisor. Anything marked as an error, such as “RLS disabled in public”, is your first fix. Write the table names down.
2Find tables without RLS (1 minute)
Open the SQL editor, paste this and press Run:
select c.relname as table_name
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where n.nspname = 'public' and c.relkind = 'r' and not c.relrowsecurity;Every name listed can be read by anyone with your app’s public key. Turn RLS on for each:
alter table public.your_table enable row level security;Your app may stop showing that data until the table has policies. That is expected: it means the table was open before. Add a policy (check 4) or ask your builder to “add RLS policies so users only see their own rows”.
3Find policies that allow everything (2 minutes)
select tablename, policyname, roles, cmd
from pg_policies
where schemaname = 'public'
and (qual = 'true' or with_check = 'true');Each row is a rule that lets the listed roles act on every row of that table. If roles is {public} or {anon}, that includes people who are not signed in. Fine for public content (a product catalogue); not fine for profiles, orders, messages or anything personal.
4Make sure users only see their own rows (2 minutes)
For personal data, a correct policy compares the row’s owner to the signed-in user. It looks like this:
create policy "Users read their own orders"
on public.orders for select
to authenticated
using ((select auth.uid()) = user_id);If a table has no column linking rows to a user (such as user_id), it can’t have a per-user rule yet. Ask your builder to add one.
5Test as a stranger (2 minutes)
This runs a query as an anonymous visitor and then undoes everything, so nothing changes:
begin;
set local role anon;
select count(*) from public.profiles;
rollback;Replace profiles with each table holding private data. You want 0 or a permission error. If the table has data and you get a real number, visitors who are not signed in can read those rows.
6Check the secret key isn’t in your front end (1 minute)
The anon (publishable) key is meant to be public. The service_role (secret) key is not: it ignores all your rules. In your project’s code or settings, search for service_role. In Vite apps, which many builders use, any variable starting with VITE_ ends up in the browser, so the secret key must never be stored in one. If it was ever exposed, rotate it in Supabase.
7Check file storage (1 minute)
Go to Storage. Buckets marked Public serve files to anyone with the link. That’s right for product images; it’s wrong for invoices, IDs or user uploads. Make those buckets private.
What to do with what you found
- Fix tables without RLS and open policies on personal data first. They are the most serious.
- Re-run checks 2, 3 and 5 after every big change your builder makes to the database.
- For the full list, including views and database functions, read the Supabase RLS security checklist.
Questions
Are apps built with Lovable insecure?
Not by default. The builder writes working code quickly, but the database rules (Row Level Security policies) still need to match who should see what in your app. Most problems we see are in those rules, not in the builder itself, and they are fixable in minutes once found.
Does this apply to Bolt, Replit, v0 or Cursor apps too?
Yes. Any app that talks to Supabase from the browser relies on the same thing: RLS policies on your tables. The checks are identical; only where you find your keys and code may differ.
My builder has its own security scan. Do I still need this?
Run it. Built-in scans and the Supabase Security Advisor catch common problems such as tables without RLS. They can't know your business rules, for example whether one customer should see another customer's invoices, so it is still worth reading your policies.
Can I test my app by trying to access the data?
Yes, your own app. The rolled-back SQL test in this guide is the safest way. Never test someone else's app or database without written permission.
General information, not a security guarantee or legal advice. Only test systems you own or are allowed to test. Rowlock is not affiliated with Supabase, Lovable or any app builder named here.