Is my Lovable app secure? What to check
Updated · Rotomal
Not automatically. CVE-2025-48757 recorded that apps generated by Lovable with insufficient Row Level Security let unauthenticated users read or write database tables; the researcher's scan of 1,645 Lovable showcase projects found 170 with inadequate RLS. Lovable disputes the CVE on the grounds that each customer is responsible for their app's data, and its own docs say you are responsible for your app's security. Check RLS on every exposed table, keep secret keys out of the browser, set storage policies and protect edge functions.
What CVE-2025-48757 found
| Item | Detail |
|---|---|
| What | Insufficient Row Level Security policy in Lovable through 15 April 2025, allowing unauthenticated access to tables of generated sites |
| Severity | CVSS 3.1 base score 9.3, critical |
| Published | 30 May 2025 |
| Status | Disputed by Lovable: each customer accepts responsibility for their app's data |
| Researcher's scan | 1,645 Lovable showcase projects scanned by 21 March 2025; 170 (about 10.3%) had inadequate RLS, across 303 endpoints |
| Data exposed, per the researcher | API keys such as Google Maps and Gemini keys, user, transaction and subscription tables, and personal data |
What Lovable checks for you now
- A Quick security scan runs automatically when you publish. Its database review covers access rules such as tables without RLS, and it audits dependencies for known vulnerabilities.
- A Deep scan reviews application code for access control, unsafe input and leaked secrets; it does not run automatically.
- Lovable detects API keys pasted into the project chat and steers you to store them in Secrets.
- Optional AI penetration testing runs through Aikido, a separate third-party service.
- Lovable states that you are responsible for your app meeting the security requirements of its use, and that its tools cannot guarantee complete security.
Self-check: 10 things to verify
- RLS is enabled on every table in public. Supabase says to enable RLS on every table in an exposed schema; run the query below.
- Every RLS table has policies that limit users to their own rows, typically comparing auth.uid() with a user_id column. With RLS on and no policies, the publishable (anon) key gets no data, so a working app usually means policies exist; read them.
- No secret or service_role key is in your frontend. Supabase says never to put a secret key in a browser, a shipped app or source control; it bypasses every RLS policy.
- The Security Advisor shows no errors such as 0013_rls_disabled_in_public (table publicly accessible), 0002_auth_users_exposed or 0010_security_definer_view.
- No policy is sitting on a table with RLS turned off (lint 0007_policy_exists_rls_disabled): the policy does nothing until RLS is on.
- Storage buckets that hold private files are not public. Public buckets are publicly accessible; private buckets need policies on storage.objects, for example limiting each user to a folder named after their ID.
- User-facing edge functions keep verify_jwt = true, the default. A function set to accept every caller is public, and code using the admin client bypasses RLS, so it must filter by the caller's ID.
- Any key that was ever exposed has been rotated: create a new key, replace it everywhere, then delete the leaked one. Hiding it is not enough.
- Tables created from 30 October 2026 have deliberate grants: anon gets only what logged-out visitors need.
- You have tested as a second user: sign in as user B and try to read and change user A's rows. Anonymous scanners do not cover this.
-- Which tables in public have RLS turned on?
select schemaname, tablename, rowsecurity
from pg_tables
where schemaname = 'public';-- Turn it on for a table that shows false
alter table public.your_table enable row level security;Run these in the Supabase SQL Editor. rowsecurity is true when row security is enabled on the table. Once RLS is on, the publishable key gets no data from that table until you add policies, so add them in the same change.
What free scanners can and cannot tell you
Free RLS checkers use what any visitor has: your frontend bundle and the public anon key. The vibe-eval checker, for example, probes public tables anonymously and lists public storage buckets. It says it does not test realtime subscriptions, Edge Functions or custom JWT claims, lists whether one logged-in user can read another's rows as a manual follow-up, and says that a clean result says nothing about an exposed service role or business logic abused through a valid session.
Run one anyway. Then cover the gaps: test as a second user, review your edge functions and check the frontend for secret keys.
When to get an outside check
Before you take payments, store personal data or sell to a business that sends a security questionnaire. Launch Lock tests the live app the way an attacker would: every table for anonymous and cross-user access with your two test accounts, storage, edge functions, auth settings and secrets in the bundle. Findings come with SQL and builder prompts, and a re-test is included. The Quick check is $29 and the Full audit $129.
Questions
Is Lovable itself insecure?
CVE-2025-48757 concerns access rules in the apps Lovable generated, and Lovable disputes it, saying each customer is responsible for their app's data. In practice the database rules of your app are yours to get right, whichever builder wrote them.
Does Lovable's security scan replace an audit?
It is a useful first pass that runs on every publish. Lovable says its tools cannot guarantee complete security and recommends a professional security review for apps that handle sensitive data or critical functions.
Is my Supabase anon key a secret?
No. Supabase says the publishable key (the legacy anon key) is safe to expose in a web page or app, because Row Level Security limits what it can reach. The secret key, or legacy service_role key, must never be in the browser.
What if my service_role key was in the frontend?
Treat it as compromised. Supabase's guidance is to fix the cause, create a new secret key, replace the old one everywhere, then delete the leaked key (a legacy service_role key is deactivated instead). A secret key bypasses every RLS policy.
Does Supabase's 30 October 2026 change fix RLS problems?
No. It stops new tables being exposed automatically, but RLS behaviour is unchanged. A table you grant to anon without RLS is still open.
Sources
- NVD: CVE-2025-48757 (description, CVSS 3.1 9.3 from MITRE, published 30 May 2025, tagged disputed) Source: nvd.nist.gov
- Intruder CVE Monitor: CVE-2025-48757 (NVD description, CVSS) Source: cvemon.intruder.io
- Matt Palmer: Statement on CVE-2025-48757 (researcher's disclosure) Source: mattpalmer.io
- Lovable docs: Security overview Source: docs.lovable.dev
- Supabase docs: Row Level Security Source: supabase.com
- Supabase docs: Understanding API keys Source: supabase.com
- Supabase docs: Storage access control Source: supabase.com
- Supabase docs: Securing Edge Functions Source: supabase.com
- Supabase docs: Security Advisor and lints Source: supabase.com
- Supabase changelog: tables not exposed to the Data API automatically Source: supabase.com
- PostgreSQL docs: pg_tables (rowsecurity) Source: postgresql.org
- vibe-eval: Supabase RLS checker (scope and limits) Source: vibe-eval.com