# Is your AI-built app leaking data?

Canonical URL: https://thorfyn.com/en/notes/is-my-ai-built-app-leaking-data

> Four Supabase checks to run before launch on a Lovable, Bolt or v0 app: row level security, the service role key, sign-in redirects and staging.

Short answer: if your Lovable, Bolt or v0 app uses Supabase, run four checks before real users arrive: row level security on every table, the service role key off the browser, sign-in links that return only to your domains, and a staging project apart from production.

- Public sources, linked
- Written by Matheus Pavaneli (https://thorfyn.com/en/about)
- Published Oct 10, 2026
- Reviewed Oct 10, 2026
- 3 min

## Why AI-built apps leak

Builders like Lovable, Bolt and v0 create the Supabase tables your app needs, but the rules that decide who may read each row are a separate step. The public key every browser receives can query the database directly, so a table without rules answers anyone who holds the key, signed in or not.

### How the leak happens

Every visitor's browser holds your public anon key. What it can read depends only on the rules of each table.

- A visitor's browser: signed in as you@…, holding the public anon key
- One request: GET /rest/v1/profiles with that key
- profiles table: 1,240 rows

- **RLS off** — 1,240 rows come back to the browser, everyone's.
- **RLS on** — One row comes back to the browser: yours.

**9.3 / 10** — is the severity NVD records for CVE-2025-48757: missing row level security in sites generated by Lovable through April 15, 2025, letting anyone read or write their tables. Lovable disputes it and says each customer is responsible for their own data. (source: [NVD](https://nvd.nist.gov/vuln/detail/CVE-2025-48757))

## Row level security on every table, tied to the user

A table with row level security off, or with a policy that allows everyone, can be read in full with the public key.

- **Check it yourself** — In the Supabase dashboard, open Authentication, then Policies. Every table in the public schema must show RLS enabled and a policy that compares a column with auth.uid().
- **Fix it** — Turn RLS on for each table and write one policy per action. For a user's own rows:

```sql
alter table public.profiles enable row level security;
create policy "own profile" on public.profiles
  for select using (auth.uid() = id);
```

## The service role key never reaches the browser

The service role key skips every rule. If it ships in the front end, anyone can copy it from the page source.

- **Check it yourself** — Open your live app, view the page source and search the scripts for service_role. Any key you find must carry the role anon.
- **Fix it** — Keep the service role key only in server code or edge function secrets, generate a new one in the dashboard, then deploy again.

## Sign-in links return only to your own domains

A wildcard in the redirect list lets a crafted sign-in link hand the session to someone else's site.

- **Check it yourself** — Authentication, then URL Configuration. The list should hold your production domain and the exact preview domains you use, with no wildcard.
- **Fix it** — Replace wildcards with exact addresses, and keep localhost only in the development project.

## A staging project apart from production

Testing against the production database means one test or one prompt can change real customers' data.

- **Check it yourself** — Check which Supabase project your preview builds point to. If it is the production address, they share data.
- **Fix it** — Create a second project for staging, copy the schema with migrations, and point previews at it.

## Questions

### Is the anon key a secret?

No. It is meant to be public and ships with every page. The rules on each table, not the key, decide what a visitor can read.

### Does Lovable add row level security for me?

Lovable's documentation asks you to review the policies of every table before going live. Treat the generated policies as a draft and check each table.

### Can I run these checks without touching code?

Three of the four are in the Supabase dashboard. The service role check needs only the page source in your browser.

## Sources

- [NVD, CVE-2025-48757](https://nvd.nist.gov/vuln/detail/CVE-2025-48757)
- [Supabase, Row Level Security](https://supabase.com/docs/guides/database/postgres/row-level-security)
- [Lovable, Connect to Supabase](https://docs.lovable.dev/integrations/supabase)

## When to ask for help

If a check fails and the app already has users, fix the first two today. A one-day triage reads sign-in, exposed data, secrets and payment, and ends in a written verdict.

- See the one-day triage: https://thorfyn.com/en/triage
- Next note: https://thorfyn.com/en/notes/lovable-bolt-v0-app-to-production
- Questions and requests: hello@thorfyn.com
- Back to the home page: https://thorfyn.com/en
