LeakyVibe

Free scan · about 15 seconds · no sign-up

Passive, read-only checks. Only scan apps you own or have permission to test.

Guides · Updated 2026-10-17

Is my Lovable app secure? What usually leaks and how to check

Short answer: Maybe. Lovable gives you a working app fast, but it can't know which data should be private. Common problems are a secret key shipped inside your public JavaScript, Supabase tables readable by anyone because Row Level Security (RLS) is off or too loose, and missing security headers. All three can be checked from the outside in minutes, and most are fixed with one prompt plus a key rotation.

Why this matters even for a small app

Everything your app sends to the browser — HTML and JavaScript — is public. Anyone can open it with the browser's developer tools; no hacking needed. If a secret key or an open database is reachable from there, a stranger can use it: run up your AI or email bill, read your users' data, or change it.

1. Secret keys inside your JavaScript bundle

When you paste an API key into the chat or into a frontend environment variable, it can end up in the JavaScript files your site serves. Variables prefixed with VITE_ or NEXT_PUBLIC_ are bundled into the public code on purpose.

Keys that must never be in the browser:

  • Supabase service_role key (or the newer sb_secret_… key) — it bypasses all database rules.
  • OpenAI, Anthropic or other AI provider keys (sk-…).
  • Stripe secret keys (sk_live_… / rk_live_…). The publishable key pk_… is fine.
  • Email API keys (Resend, SendGrid…), AWS keys, GitHub tokens, database connection strings.

The Supabase anon key (or sb_publishable_… key) is designed to be public. It's only safe if RLS is set up correctly — see the next point.

2. Supabase tables with Row Level Security (RLS) off or too open

Lovable apps usually talk to Supabase straight from the browser using the public anon key. Row Level Security is what decides which rows each visitor may read or write. If RLS is disabled on a table — or a policy says “allow everyone” — anyone with your anon key (which is in your page) can read that table.

Typical risky tables: profiles, users, orders, messages, leads, waitlist, anything with emails, phone numbers or payments.

3. Missing HTTPS redirect and security headers

Less dramatic, but easy wins: your site should redirect http:// to https:// and send a few standard headers.

  • Strict-Transport-Security — forces HTTPS.
  • X-Frame-Options: DENY or a Content-Security-Policy with frame-ancestors — stops other sites from embedding yours to trick clicks (clickjacking).
  • X-Content-Type-Options: nosniff and a Referrer-Policy.

Also check that files like /.env or source maps (.map) are not publicly downloadable.

How to check your Lovable app yourself

  1. Open your live app, press F12 (developer tools), go to Sources (Chrome) or Debugger (Firefox) and use “Search in all files” for: service_role, sk-, sk_live, rk_live, secret, re_ (Resend), SG. (SendGrid). Any real secret there is a leak.
  2. In the Supabase dashboard open Table Editor: every table should show RLS enabled. Then open Authentication → Policies and look for policies with “true” as the condition on tables that hold personal data.
  3. Run Supabase's Security Advisor (Database → Advisors) and fix anything it flags.
  4. Check headers with your browser's Network tab (click the first request → Response Headers) or any header-checking tool.

Or paste your URL into the free LeakyVibe scan above: it does these checks from the outside, read-only, in about 15 seconds, and lists the problems in plain language.

How to fix what you find

  1. Leaked secret key: rotate it first (create a new key in the provider dashboard and delete the old one) — removing it from the code is not enough, because old versions may be cached or copied already. Then move the call that needs it into a Supabase Edge Function or another server-side function and store the key as a secret there.
  2. RLS off: enable RLS on every table, then add policies that only allow what's needed — for example users can only read and edit rows where user_id = auth.uid().
  3. Headers: add them in your hosting settings (for example vercel.json / netlify.toml headers) or ask your builder to add them.

A prompt you can paste into Lovable as a starting point:

Review my Supabase setup. Enable Row Level Security on every table. Add policies so each user can only select, insert, update and delete their own rows (user_id = auth.uid()). Public tables should be read-only. Make sure no service_role key, secret API key or Stripe secret key is used in frontend code; move those calls into Supabase Edge Functions using secrets. List every change you made.

After the fix, test again: log out (or use a private window) and confirm private data no longer loads.

Short checklist

  • No secret keys in the public JavaScript (only anon/publishable keys).
  • RLS enabled on every Supabase table, with no “allow everyone” policy on personal data.
  • Any key that was ever exposed has been rotated.
  • HTTPS redirect and basic security headers in place.
  • No public /.env or source map files.

A passive scan like LeakyVibe is a quick first check, not a full security audit. If you handle payments or sensitive data, consider a professional review too.

Free scan · about 15 seconds · no sign-up

Passive, read-only checks. Only scan apps you own or have permission to test.