Security by tool
Is my Lovable app secure?
Lovable itself is not the problem — but the apps it produces go live with a predictable set of mistakes. The four most common are: Supabase tables without Row Level Security, API keys in the shipped JavaScript, publicly reachable source maps, and missing security headers. All four can be checked from the outside, without access to your source code, and all four take minutes to fix. The most expensive one is the missing Row Level Security: it lets any visitor to your site download your entire users table.
The scan is free and takes about twenty seconds. You see straight away how many findings there are and how serious they are.
Scan your own app for freeWhy Lovable apps have predictable holes
Lovable produces code that works. That is a different thing from code that is protected. If you write “create a table for user profiles”, the table appears — the access rules do not, because you did not ask for them.
Then there is the architecture: a Lovable app is a single-page app that talks to Supabase directly. The key it needs has to sit in the browser; it is public, and that is by design. What makes it safe are the rules in the database. Without them, that public key is a master key.
This is not a complaint about the tool. It is the difference between “it runs” and “it holds up”, and you only know that difference once you have seen it.
1. Supabase tables without Row Level Security
By far the most consequential mistake. Without Row Level Security, Supabase does not check who is asking — it simply answers. The anon key your app asks with sits publicly in your JavaScript.
In practice: anyone who opens your site, opens the developer tools and copies the key can download your entire table. Not just their own rows — all of them.
This exact pattern is documented as CVE-2025-48757, published on 29 May 2025 with a severity of 9.3 out of 10. The official description reads: “An insufficient database Row-Level Security policy in Lovable through 2025-04-15 allows remote unauthenticated attackers to read or write to arbitrary database tables of generated sites.”
The entry is marked “disputed”: Lovable argues that securing your own data is each customer’s responsibility. That objection is not unreasonable — but it changes nothing about the situation you are in. If your tables are open, they are open, regardless of whose job it was.
-- In the Supabase console under Authentication → Policies ALTER TABLE profiles ENABLE ROW LEVEL SECURITY; CREATE POLICY "Read own profile" ON profiles FOR SELECT USING (auth.uid() = id);
2. Keys that do not belong in a browser
The Supabase anon key belongs in the frontend. An OpenAI, Stripe secret or Resend key does not — and still ends up there regularly, because the fastest route to a working prototype is calling the API straight from the browser.
With Vite the rule is: anything starting with `VITE_` is baked into the bundle at build time. The name of the variable says nothing about whether the value is secret. `VITE_OPENAI_KEY` is as public as the text on your homepage.
Once such a key has been shipped, treat it as compromised. Removing it from the next build is not enough — the old bundle was public, and bots comb public bundles automatically.
3. Source maps in production
Source maps translate the built bundle back into your original code. In development they are indispensable; publicly reachable they hand over your unbuilt code — filenames, comments and folder structure included.
That is rarely a hole in itself, but it is the map: whoever has it no longer has to guess where sign-in is checked or which endpoints exist.
// vite.config.ts
export default defineConfig({
build: { sourcemap: false },
});4. Missing security headers
Content-Security-Policy, HSTS, X-Frame-Options, Referrer-Policy. None of them opens a hole — they decide whether a small hole becomes an exploited one.
In Lovable apps they are almost always missing, because they do not live in application code but in the delivery configuration. If you have never written one, you do not know they exist.
What you can check yourself in five minutes
Open your app, press F12, go to “Network” and reload. Look for requests to `supabase.co`. Copy one such address including its `apikey` parameter and open it in a private window — signed out. If data comes back, Row Level Security is missing.
For the keys: in the developer tools under “Sources”, open the largest `.js` bundle and search for `sk-`, `sk_live` or `service_role`. A hit is a hit.
Those two moves find the two worst mistakes. Everything else — headers, source maps, DNS, dependencies, forgotten subdomains — we check automatically.
What we check automatically
- Row Level Security on Supabase tables
- Keys in the shipped JavaScript
- Public source maps
- Security headers
Frequently asked questions
- Is Lovable insecure?
- No. Lovable as a platform is not the problem. But the apps it generates are not protected as shipped: Row Level Security is off, security headers are missing, and keys easily end up in the frontend. Those are settings, not flaws in the tool.
- Is it enough that Claude or Cursor reviewed my code?
- It helps, but it covers something else. An AI assistant reads your source. We check what your server actually ships — not the same thing. The code says `import.meta.env.VITE_STRIPE_KEY`, which looks harmless; only the build substitutes the real value. And whether your Supabase rules hold is a fact about your database, not your repository.
- How do I find out whether my Supabase tables are open?
- Call one of your project’s REST addresses with the public anon key in a private browser window, signed out. If rows come back, the table is readable without authentication. Our deep scan does exactly that — after you prove the domain is yours.
- Can I have my Lovable app checked for free?
- Yes. The scan is free and needs no account. You see how many findings there are, how serious they are and which area they fall into; some of the lighter findings we show in full. The complete report with every location costs a one-off €9.49 per domain.