Case study
Documented public incidentCVE-2025-48757: 170+ Lovable Apps With Open Supabase Tables
Based on publicly reported incidents with linked sources — not a fictional client narrative. Describes the real problem and how I fix the same pattern for paying clients.
Subject
Documented: Linkable (linkable.site) + 170 apps on Lovable Launched
Stack
Lovable, React, Supabase (Postgres + PostgREST), public anon key
Outcome
CVSS 8.26; 303 endpoints / 170 projects exposed in scan; payment_status bypass on Linkable
This case study is not a fictional client story. It documents a real, searchable vulnerability disclosure — CVE-2025-48757 — and the rescue pattern I run when founders discover their Lovable app is in the same state.
The documented incident
Discovered: March 20, 2025 by Matt Palmer (Replit) while testing Linkable (linkable.site) — a Lovable-built marketing site for generating websites from LinkedIn profiles.
What he found: By modifying a normal Supabase REST request from the browser (equivalent to SELECT *), unauthenticated visitors could read the full users table — emails and profile data for 500+ users who had used the site. The issue was not a "leaked secret key"; Supabase's public anon key is designed to be client-side. The failure was missing or insufficient Row Level Security (RLS).
Scope scan (March 21, 2025): Palmer and Kody Low scanned projects listed on Lovable Launched and found 303 vulnerable endpoints across 170 projects (~10.3% of 1,645 analyzed) — exposing users, transactions, subscriptions, Gemini API keys, Google Maps tokens, and more.
Public confirmation: On April 14, 2025, Palantir engineer Danial Asaria publicly demonstrated the same class of exploit on live Lovable apps.
CVE published: May 29, 2025. CVSS v3.1 base score 8.26 (High). No vendor patch — mitigation is correct RLS configuration per table.
The payment bypass follow-up (same app)
In a May 24, 2025 re-test of Linkable (by then a paid product maintained by a Lovable employee), Palmer documented something worse than read access: by POSTing to /rest/v1/website_generation without an auth header, an attacker could insert records with "payment_status": "paid" — bypassing Stripe entirely. That write path persisted even after the initial disclosure and Lovable's April "security scan" release.
Why this keeps happening to non-technical founders
Lovable apps call Supabase directly from the browser using the anon key. Security depends entirely on RLS policies matching your business logic. The AI builds working demos; it does not reliably ship least-privilege policies. Lovable's scanner (released April 24, 2025) checks whether RLS exists, not whether it works — which researchers called a false sense of security.
Nothing looks broken in the UI. Data leaks quietly until someone curls your REST API or reads the CVE.
How I fix this pattern (my engagement)
When a founder contacts me after reading about CVE-2025-48757 or noticing "RLS disabled" badges in Supabase, this is the playbook:
- External verification — curl each table with only the anon key (same method attackers use).
- Table inventory — map every table to actual frontend and Edge Function queries.
- Policy-by-policy RLS — enable RLS one table at a time with correct
auth.uid()checks so the app doesn't go blank. - RPC and Edge Function audit — lock down functions like
get_gemini_api_keythat appeared in the scan. - Key rotation if
service_roleever appeared in client code.
Typical engagement: $299 triage (48h audit + video walkthrough) → $799 Priority Fixes for the RLS migration without production downtime.
What you should search to verify this yourself
CVE-2025-48757mattpalmer.io lovable RLSlinkable.site lovable vulnerabilitylovable launched supabase exposed
Sources
- CVE-2025-48757 disclosure (Matt Palmer)
- Statement on CVE-2025-48757 — scan methodology & Linkable timeline
- NVD entry
Worried your app is in the same state? RLS fix guide or $299 security triage.
Primary sources
Facing something similar right now?
Tell me what broke and get a fixed-price answer — usually within 48 hours for triage.
Get help with this