Short answer
Nobody can honestly promise an app is secure, but you can find out whether the common holes are open. For a Lovable app, the big one is the database: if its Row Level Security rules are missing or too loose, anyone can read your users' data with the public key that ships in your site's code. Run Lovable's security scan, then test the rules as a stranger and as another user.
Where your app's data lives
A Lovable app's data sits in a Supabase database (Postgres), either through Lovable Cloud or a Supabase project you connected. Your website talks to that database directly from the visitor's browser, using a public key that's built into your site's JavaScript. Anyone can find it, and that's normal.
What stops a stranger from using that key to download your users table is Row Level Security (RLS): rules on each table that say who can read and change which rows. The AI writes those rules as it builds features. Most are fine. The ones that aren't tend to look harmless, like a rule that says "logged-in users can read profiles" when it should say "users can read their own profile".
This isn't a theoretical worry. In May 2025, Semafor reported that 170 of 1,645 Lovable apps checked let anyone read their users' data, and in September 2026 TechCrunch reported UpGuard finding 16,000 Supabase databases exposing personal data.
What we saw in real Lovable projects
We ran Lockstamp offline on public GitHub projects built with Lovable and Supabase, rebuilding each database from its public migration files. No live sites were touched and individual results aren't published.
- 14 of 27projects had at least one attack that worked
- 12serious holes after a closer review, all in 1 project
- 92results left for a human decision
All numbers are in rebuilds from public migration files, not live apps. The "human decision" results are mostly data that may be meant to be public, like listings or reviews, or rules too complex to change safely without knowing the app. That's the honest picture: serious holes are real but not everywhere, and most findings need someone who knows the app to make the call.
7 checks you can do yourself
1. Run Lovable's security scan, and read it
Lovable has a built-in security scan. Run it before you publish and read each warning rather than clicking past it. If your project uses its own Supabase project, also open Security Advisor in the Supabase dashboard. Both are free. Both mostly review your settings; they don't try the attacks.
2. Make sure every table has RLS on
Open your SQL editor (on Lovable Cloud: More, then Cloud, then
SQL editor) and run this. Any table showing false is open to anyone.
select c.relname as table_name, c.relrowsecurity as rls_on
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where n.nspname = 'public' and c.relkind in ('r', 'p')
order by rls_on, table_name;
3. Look for rules that let everyone in
A rule whose condition is just true lets every request through. That's fine for a public product
list. It's a leak on profiles, messages, orders or anything personal.
select tablename, policyname, cmd, roles, qual, with_check
from pg_policies
where schemaname = 'public' and (qual = 'true' or with_check = 'true');
4. Check users can't promote themselves
If your profiles table has a role, is_admin, credits or
plan column, and users can edit their own profile, they can usually change those too. RLS controls
rows, not columns. Ask whether a normal user could run
update profiles set role = 'admin' on their own row. If yes, that needs fixing (see below).
5. Search your code for secret keys
In your project's code (in Lovable's code view or on GitHub), search for service_role,
sk_live, sk- and secret. Anything in front-end files or in variables
starting with VITE_ ends up in the browser. The Supabase public key is fine there; a
service_role key, a Stripe secret key or an AI provider key is not. If you find one, rotate it in
that provider's dashboard and move the call into a server function.
6. Open your app as a stranger
Open your site in a private window without logging in. Open the browser's developer tools, go to the
Network tab, and use the app. Look at requests to /rest/v1/. If any return other
people's names, emails or messages while you're logged out, anyone on the internet can see them too.
7. Open it as a second user
Sign up two test accounts. Create something private with the first (a note, an order, a message), then log in as the second and look for it, including in the Network tab. This catches a common leak in AI-built apps: rules that check "is logged in" instead of "owns this row".
Checks 2, 3, 4, 6 and 7 are what the free Lockstamp check automates: real attacks as a stranger and as a second user, on a private copy in your browser.
Run the free checkHow to get it fixed
Ask Lovable to fix it
You can paste a prompt like this into Lovable, adjusted for your tables:
Review the Row Level Security on every table. Users should only be able to
read, update and delete their own rows (matched on user_id = auth.uid()).
Remove any policy that uses "true" on tables with personal data.
Users must not be able to change role, is_admin, plan or credits columns.
Show me the SQL migration before applying it.
Then check the result. AI fixes can go too far (your app stops showing data) or not far enough (an open rule is left behind). Re-run checks 6 and 7, or the free check, after every change.
Or fix it with SQL
Policies add up: if any rule lets everyone in, owner-only rules don't help, so drop the open ones first (list
them with the query from check 3). For a table like notes with a user_id column:
alter table public.notes enable row level security;
-- Drop each open rule the check 3 query listed, for example:
drop policy if exists "Enable read access for all users" on public.notes;
create policy "Owners read their notes" on public.notes
for select to authenticated using ((select auth.uid()) = user_id);
create policy "Owners add their notes" on public.notes
for insert to authenticated with check ((select auth.uid()) = user_id);
create policy "Owners edit their notes" on public.notes
for update to authenticated
using ((select auth.uid()) = user_id)
with check ((select auth.uid()) = user_id);
create policy "Owners delete their notes" on public.notes
for delete to authenticated using ((select auth.uid()) = user_id);
Stop users editing their own role
revoke update on public.profiles from authenticated;
grant update (display_name, avatar_url) on public.profiles to authenticated;
List every column your profile form saves, or those edits will start failing. If users create their own profile row, they could set role there too, so give it a default and limit the insert grant the same way.
If your app breaks after a change, the RLS not working guide covers the usual causes. For the full set of checks, see the RLS checker guide.
Or have it done for you
If you'd rather not touch SQL, Mark M. applies the fix to your project, tests your main features and sends you the before-and-after proof. Intro price from $150 for the first few clients, hired and paid through Upwork (opens in a new tab). It covers the database rules that were checked; no fix is a guarantee that no other weaknesses exist.