Lovable app security: what to check before you launch
Lovable turns a prompt into a working React app with a Supabase backend in minutes. The speed is real, and so is the gap it leaves: the code that decides who can read your data is the part you never looked at. Here is what usually goes wrong and how to check it from outside.
How a Lovable app is put together
A typical Lovable project is a Vite and React single-page app. The browser downloads one JavaScript bundle, and that bundle talks directly to Supabase using the project URL and the public anon key. There is no server of yours in between, so every rule about who may read or change a row has to live in the database itself, as Row Level Security policies.
That design is fine when the policies are right. The problem is that the app works the same whether they are right or not. You click through your own app, everything loads, and nothing tells you that a stranger with the same anon key could load it too.
The gaps we see most often
- A table with RLS turned off, or with a policy like
using (true)that was added to make an error go away. Anyone can then read it with the anon key from your JavaScript. - A secret key pasted into the frontend: an OpenAI, Stripe or Resend key that the AI put into a component because that was the fastest way to make a feature work.
- The Supabase
service_rolekey in the bundle instead of the anon key. It bypasses every policy, so it is a full database credential. - No security headers on the custom domain: no Content-Security-Policy, no protection against framing, no HSTS.
- A custom domain that sends email with no SPF or DMARC record, so anyone can send mail that looks like it came from you.
Lovable ships its own security scan inside the editor, and it is worth running. It looks at the project from the inside. Shypset looks at the deployed site the way a visitor or an attacker does, on any domain, including headers, TLS, DNS and email, which an editor scan does not see.
What Shypset checks on a Lovable app
We recognise a Lovable build from references in the page source, the Lovable badge, legacy gptengineer.app markers or hosting on *.lovable.app, and tune the fix prompts to it. Then the checks run in two levels.
- Public, on every scan: we read the homepage and the scripts it loads, the same files your browser gets. We search them for about 40 kinds of secret keys, decode any Supabase JWT to see whether it is a
service_rolekey, look for exposed source maps, and check headers, TLS, DNS and email records. - Verified, after you prove you own the domain: we take the Supabase tables your bundle references and ask each one for a single row with the anon key, exactly as an anonymous visitor could. We record only whether rows came back and the column names, never the data.
Shypset is a passive external check. It does not log in to your app and does not test application logic such as SQL injection or IDOR, so a clean report means nothing is visible from outside, not that the app is secure.
How to fix it in Lovable
Most fixes are one prompt away, because Lovable can edit both the frontend and the Supabase migrations. Ask it to enable RLS on every table and to write policies that tie each row to auth.uid(). Move any secret key out of the frontend into a Supabase Edge Function and call that function instead. Then publish, and rescan to confirm the finding is gone.
Example finding
This is what a finding from the Verified probe looks like in a report, with the fix prompt we generate for Lovable.
profiles is readable without loginEvidence
Request: GET /rest/v1/profiles?select=*&limit=1 with the anon key HTTP status: 200 Rows returned: yes Columns (first 5): id, email, full_name, phone, created_at
Fix prompt
In this Lovable project the Supabase table `profiles` can be read by anyone with the anon key. Write a migration that enables Row Level Security on `profiles` and adds policies so a signed-in user can select and update only the row where `id = auth.uid()`. Do not add any policy for the anon role. Check every other table the app uses the same way and list what you changed.
Questions
- Is the Supabase anon key in my Lovable app a leak?
- No. The anon key is meant to be public. It is only safe when every table has RLS policies, which is exactly what the Verified probe tests.
- Do I need to give Shypset access to my Lovable project?
- No. You paste the URL of the deployed app. No code access and no Supabase credentials are needed.
Scan your Lovable app
Paste the URL of your published app on the home page. The first scan is free and takes about a minute.
Scan your Lovable app