LR-01

Your Database Is Public. You Just Don't Know It Yet.

Your app has a login page. Users sign in. The dashboard shows their data. Everything works exactly as expected.

But behind the login screen, your database is answering requests from anyone — authenticated or not. Every row, every table, every user record. No errors. No warnings. No logs. The app looks fine because the app is fine. The database just doesn't know who's asking.

This is not a theoretical risk. In May 2025, security researchers disclosed CVE-2025-48757 after scanning 1,645 Lovable-generated apps — 170 of them were leaking user data to the public internet. Names, emails, phone numbers, home addresses, financial records. A separate audit found 20.1 million rows exposed across 71 YC startups using Supabase, with 28% leaking personally identifiable information.

The founders had no idea.


Who This Is For

  • Founders who built with Lovable, Bolt, Cursor, or similar AI tools and use Supabase as their database
  • Developers who set up Supabase auth but aren't sure about Row Level Security (RLS) configuration
  • Teams approaching launch with real user data — payments, personal information, health records
  • Anyone who assumed that "having authentication" means "the data is protected"

If your app uses Supabase and was substantially built by an AI tool, this is not an edge case — it's a measured pattern across thousands of scanned applications.


What Founders Experience

The pain is invisible. That's what makes it dangerous.

  • The app works perfectly. Users log in, see their data, perform actions. Nothing looks wrong. Nothing feels wrong. The UI enforces boundaries — but the database doesn't.
  • There are no error messages. When RLS is disabled, Supabase doesn't throw errors. It returns data. All of it. To anyone who asks.
  • A curious user discovers the problem before you do. Someone opens Chrome DevTools, sees the Supabase URL and anon key in network requests, and writes a simple query. They get back every user's data. Your data. Your customers' data.
  • The breach report arrives from outside. A security researcher, a competitor, a journalist, or a customer emails you: "I can see other users' data." By then, the exposure may have been live for weeks or months.
  • The fix is simple — but the damage is done. Adding RLS takes minutes. Rebuilding user trust takes months. Answering a GDPR inquiry takes lawyers.

What's Actually Happening

When you create a table in Supabase, Row Level Security is disabled by default. This means the table is fully accessible through the public Supabase API — the same API your frontend uses.

Your app's frontend uses the anon key — a public key visible in every browser. With RLS disabled, anyone who has this key (which is everyone who visits your site) can query any table directly, bypassing your entire UI layer.

Three failure modes create this exposure:

1. RLS Never Enabled

The most common case. AI tools generate CREATE TABLE statements without ALTER TABLE ... ENABLE ROW LEVEL SECURITY. The table works perfectly in development. It works perfectly in production. It's also publicly readable.

This is what caused CVE-2025-48757 (CVSS 9.3): 170 Lovable apps exposed because RLS was simply never turned on. One breach exposed 13,000 users' home addresses and financial records.

2. RLS Enabled, But Policies Are Wrong

AI tools sometimes enable RLS but generate policies like USING (true) — which means "allow everyone to read everything." Syntactically valid. Functionally useless. The table has RLS "enabled" but provides zero protection.

Other common mistakes:

  • Missing WITH CHECK on INSERT/UPDATE — users can insert rows with any user_id, or change user_id to steal ownership of other rows
  • auth.uid() not handling null — when no session exists, the function returns null, which can match unexpectedly
  • Policies on SELECT but not INSERT/UPDATE/DELETE — the table is "read-protected" but fully writable

3. RLS Disabled During Development, Never Re-Enabled

AI tools sometimes disable RLS to make tests pass or to avoid "permission denied" errors during development. The developer — or the AI — intends to re-enable it later. It never happens. The app goes to production with a database that has no access control at all.


What This Puts at Risk

User trust. Once users learn their data was exposed, they leave. A billing error gets a refund; a data exposure gets a screenshot on Twitter.

Legal liability. GDPR requires notification within 72 hours of discovering a breach. Fines can reach 4% of global turnover or EUR 20 million. A Dutch DPA ruling established that founders can be held personally liable when they "knew, had authority to stop, and consciously omitted" action.

Business survival. The Moltbook social network — built entirely with AI, praised by Elon Musk — exposed 1.5 million API tokens, 35,000 email addresses, and 4,000 private messages. The fix was two SQL statements. The reputational damage was covered by Wiz, Fast Company, and PCMag within 48 hours.

Launch momentum. One founder's Lovable app exposed 487 user records on day 5. Two beta users left permanently. The fix took 10 minutes — one line of SQL. But the launch momentum was gone.


How Trust Score Detects It

Trust Score runs two checks that catch data exposure before it reaches production:

AUTH-02: RLS enabled on all tables. Scans every table in your Supabase schema and verifies that Row Level Security is active — not just that the table exists, but that access control is enforced.

AUTH-03: RLS policies have WITH CHECK. Verifies that INSERT and UPDATE operations are restricted, not just SELECT. A table with read protection but no write protection is still vulnerable.

These checks exist because the most common founder misconception is: "I have authentication, so my data is protected." Authentication verifies who the user is. RLS controls what they can access. Without RLS, authentication is a locked front door with no walls.


Real Incidents

CVE-2025-48757 — 170 Lovable apps exposed (May 2025). Security researcher Matt Palmer scanned 1,645 apps from Lovable's showcase. 10.3% had critical RLS failures. Exposed data included names, emails, phone numbers, home addresses, personal debt amounts, and API keys. CVSS 9.3.

Moltbook — 1.5 million tokens exposed (January 2026). Wiz researchers found the Supabase API key in client-side JavaScript and no RLS. A single curl command returned 1.5 million authentication tokens, 35,000 email addresses, and 4,000 private messages.

YC startup audit — 20.1 million rows exposed (2025). A security audit of 71 YC startups using Supabase found that 61% had some exposure. 28% were leaking PII. One education startup exposed 8.5 million rows of student transcripts.

Tea App — 72,000 images leaked (2026). 13,000 government ID photos, 1.1 million private messages, 1.6 million users affected. Covered by BBC and NBC News. The breach showed how rapid, AI-assisted deployment without proper access controls can expose sensitive user data at massive scale.

Indie app scan — 11% exposure rate (2026). A scan of 20,052 launch URLs from indie directories found 2,217 domains with exposed Supabase data. 2,325 critical exposures across apps that looked finished, functional, and live.


Detection: How to Check Your Own App

Check 1: Are your tables protected?

Open Supabase Dashboard → Authentication → Policies. Look at every table. If a table shows "RLS disabled" or has no policies, it is publicly accessible.

Check 2: Can you query without auth?

Open your browser's DevTools. Find your Supabase URL and anon key in network requests. Then run:

curl 'https://YOUR-PROJECT.supabase.co/rest/v1/YOUR-TABLE?select=*' \
  -H "apikey: YOUR-ANON-KEY" \
  -H "Authorization: Bearer YOUR-ANON-KEY"

Interpretation: If this returns data, your table is publicly readable. Any visitor to your site can do the same thing.

Check 3: Are your policies actually restrictive?

Check for USING (true) policies — these allow everyone to read everything despite RLS being "enabled." Check that INSERT/UPDATE policies include WITH CHECK (auth.uid() = user_id) or equivalent.


Related Launch Risks


FAQ

Our app has authentication. Doesn't that protect the data?

No. Authentication verifies who the user is. Row Level Security controls what data they can access. Without RLS, a logged-in user can read every other user's data. Without RLS, even an unauthenticated visitor with the public anon key can read everything. Authentication without authorization is a locked door with no walls.

We built with Lovable/Bolt. Does the AI handle RLS?

Not reliably. CVE-2025-48757 found that 10.3% of Lovable showcase apps had critical RLS failures. AI tools often generate tables without enabling RLS, or generate policies like USING (true) that look correct but protect nothing. The AI optimizes for "code that works," not "code that's secure."

How long does it take to fix?

Enabling basic RLS takes 5–30 minutes per table. Designing correct policy logic — especially for complex access patterns — can take longer. The hard part is discovering the problem in the first place. Your app gives you no signal that anything is wrong.

Can someone actually find my Supabase URL and query my data?

Yes. Your Supabase project URL and anon key are visible in every browser that loads your app. They're in the JavaScript bundle, in network requests, in the page source. This is by design — the anon key is meant to be public. RLS is what makes this safe. Without RLS, it makes your database a public API.

What about Supabase's built-in security advisor?

Supabase's dashboard shows warnings about missing RLS, but it checks whether RLS is enabled — not whether your policies are correct. A table with USING (true) passes the dashboard check but provides zero protection. Lovable's security scanner has the same limitation. Trust Score checks both: RLS enabled (AUTH-02) and policies actually restrictive (AUTH-03).


Is This Happening in Your App?

Run a free Trust Score scan — 24 safety checks across auth, billing, and admin. Results in seconds.