Securealy
Guide · Lovable · Supabase

Is my Lovable app secure?

Not by default. A Lovable app is secure when every Supabase table has row level security on with a policy you can read, no secret key is in the bundle, and the routes behind the page refuse anonymous requests. The built-in scan checks the first from inside. The rest you check from outside, with the URL.

Is my data readable with the key in the page?

Often, yes. Your app ships a Supabase URL and a publishable key in its JavaScript, and that key talks to the database directly. A table without row level security answers it with every row. In the first public scan of Lovable showcase apps, 170 of 1,645 let anyone read user data this way.

The publishable key (called the anon key until 2025) is public by design. Supabase's own documentation says it plainly: until you enable row level security and write a policy, anyone holding your project's publishable key can read and write every row. Nothing you do to your pages or your API changes that path, because a request made with the key never touches your pages or your API.

The incidents are consistent. CVE-2025-48757, disclosed in May 2025, covered Lovable projects whose tables had RLS off or a policy of USING (true); the researcher reported names, home addresses, debt amounts and third-party API keys from the 170 affected showcase apps. In February 2026 an education app featured by Lovable exposed 18,697 user records through an access rule that denied signed-in users and allowed anonymous ones. In September 2026 UpGuard found 16,326 Supabase databases with readable tables, and named the reason: tables created through the API, which is how a coding agent creates them, do not get RLS by default. Tables made in the dashboard do.

Two checks settle it for your project. supabase-rest-exposed runs on any URL and asks the database API, with your own page's key, whether it will list your tables. supabase-anon-row-read runs after you verify ownership and asks each table for one row. A table that is public on purpose, such as a catalogue, still shows up, so you confirm it is intended. The fix is the same every time: RLS on for every table, zero policies until one is justified, and a written reason for each table that stays open.

Is there a secret key in my bundle?

Check, because the publishable key is fine and the secret key is not. A secret key (service_role, or the newer sb_secret_ format) bypasses every RLS policy, so one in the JavaScript is a full copy of your database for anyone who views source. The check that finds it is passive and takes seconds.

Supabase's key documentation draws the line: the publishable key only reaches what row level security allows, and a secret key bypasses every Row Level Security policy you have. Never put one in a browser, a shipped application, or source control. The way it gets there is a variable name. Anything prefixed VITE_ or NEXT_PUBLIC_ is inlined into the bundle at build time, so a secret under such a name is published on the next deploy, and it stays published even after the source is fixed until the site is rebuilt.

The same applies to a Stripe secret key, an email provider key, or a model provider key. secrets-in-bundle fetches the home page and its first-party scripts and looks for the shape of each provider's secret; a hit is a launch blocker. source-maps checks whether your build also serves the original source, comments included, which is how an inlined constant becomes readable. If either finds something, the order is rotate first, then fix the code, following the rotation guide.

What does Lovable's built-in scan cover?

Lovable runs a free quick scan on every publish that reviews database access rules, including tables without row level security, npm dependency vulnerabilities and connected MCP servers, and offers a deeper on-demand scan of code. Lovable itself says these tools cannot guarantee complete security and do not replace a thorough review.

The security documentation describes two scans. The quick scan runs automatically every time you publish and covers a database review (tables without per-record access control, rules that let everyone through, leaked-password protection off), a dependency audit and an MCP server check. The deep scan does not run on its own; you start it, and it looks at access control, unauthenticated endpoints, injection, leaked secrets, payments and exposed personal data. Both are free and use no credits. Publishing is blocked on critical findings only if you turn that setting on. A paid penetration test through a partner is a separate, opt-in product.

Read the limits in the same document. The scans cannot guarantee complete security and do not replace a thorough security review. Lovable's own June 2026 post adds that the basic scan does not analyze your application code for logic flaws or vulnerabilities unique to how your app is built. The February 2026 education app had passed through a Lovable project with a scan available; the inverted access rule was a logic flaw. Lovable's response at the time was that applying the recommendations is at the user's discretion.

So the scan is worth running, and it is a view from inside the project. It cannot see what a stranger sees at your domain: the headers your host sends, the email domain your sign-in codes come from, whether a missing page answers 404, whether the Stripe key on the live domain is a test key, or what a request to your API returns with no credential. That is the view the grade takes.

What should I check from outside?

Grade the live URL. Fifty-one checks run on any address: the key and tables, secrets and source maps, TLS and headers, SPF, DKIM and DMARC on the sending domain, the 404 status, the Stripe key mode, legal pages and analytics. Seven more run after you verify ownership, including anonymous row reads and open routes.

Start with the blockers, because one caps the grade at D and two at F. secrets-in-bundle, supabase-anon-row-read, open-admin-routes, exposed-env-files and exposed-git are the classes behind nearly every incident in the ledger. Then the things that are not security but stop a launch: auth-sender-authenticated, which decides whether your magic-link emails arrive; stripe-test-key-in-prod; not-found-page; legal-pages.

Lovable apps on a lovable.app subdomain can be graded before the domain is attached; the mail and domain checks skip there because the subdomain carries no mail of its own, and they run the moment the real domain answers. Each failed check has a page with the evidence pattern, the fix, and a prompt to paste back into Lovable that reproduces the finding without changing anything. The three local checks that need your own keys, rls-policies, supabase-auth-config and stripe-webhook-wiring, run on your machine and never send a key anywhere.

Grade it

Grade the app, not the builder

Paste the lovable.app URL or the live domain. The grade lists every check above with its evidence for your site, in under ten seconds. Two free grades a day.

Checks this guide refers to: supabase-rest-exposed, supabase-anon-row-read, rls-policies, secrets-in-bundle, source-maps, open-admin-routes, auth-sender-authenticated, stripe-test-key-in-prod, not-found-page.