In May 2025, over 170 production apps built with Lovable had their entire Supabase databases publicly readable — no login, no exploit, no technical skill required.
Security researchers Matt Palmer and Matan Getz independently identify that large numbers of Lovable-generated production apps have Supabase RLS disabled. The anon key, present in every client bundle, provides unrestricted database access.
The vulnerability class receives a formal CVE identifier. Public documentation confirms 170+ affected apps, all in production with real users. The disclosure is published via the National Vulnerability Database and covered in security research blogs.
Lovable updates its documentation and interface guidance around RLS. Supabase publishes clarifications on default RLS status. Neither platform pushes a retroactive fix to deployed apps — the configuration change must be made by each developer in their own Supabase project.
RLS misconfiguration remains the most common critical finding in AI-built apps scanned by Launch Ready Code. The issue is not limited to Lovable — Bolt.new, Cursor, v0, and Replit apps using Supabase exhibit the same pattern when RLS is not manually configured.
Supabase provides two primary API credentials:
The anon key being public is correct behaviour, documented in Supabase's own setup guides. The failure in CVE-2025-48757 was not the key being present in the bundle — it was the absence of RLS policies that should have restricted what the key can access.
When Supabase row-level security is disabled on a table, the Supabase PostgREST API applies no row filtering whatsoever. Any request — authenticated or anonymous — that reaches the table's REST endpoint returns all rows. The check that PostgREST performs is: "Is the caller authorised to use this Supabase project?" (answered by the valid anon key). Without RLS, it never asks: "Is the caller authorised to see these specific rows?"
For any affected app, the attack was a single HTTP request:
GET https://[project-ref].supabase.co/rest/v1/users?select=*
apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
HTTP/1.1 200 OK
Content-Type: application/json
[
{ "id": "uuid", "email": "user@example.com", "created_at": "...", ... },
{ "id": "uuid", "email": "another@example.com", "created_at": "...", ... },
...
]
The anon key is extracted from the page's JavaScript source (one browser DevTools search). The project ref is in the same URL. The table name is guessable from common Supabase conventions (users, profiles, orders, payments). No authentication, no session, no exploit code.
Across the 170+ affected apps, the exposed data included:
Three independent factors converged to create this vulnerability class:
Every table created in Supabase has rowsecurity = false until explicitly enabled. This is a deliberate Supabase design choice — enabling RLS before policies are written locks out all users including authenticated ones, which would break apps in an equally confusing way. Supabase documents this clearly but relies on developers to take the enabling step.
Lovable (and Bolt, Cursor, v0, and other AI builders) generates CREATE TABLE statements and migration files. None of the major AI builders in 2025 included ALTER TABLE ... ENABLE ROW LEVEL SECURITY; or policy creation in their default schema output. The generated code was functional but insecure by default.
Supabase did not surface a prominent warning at deploy time or via the dashboard alerting developers that public-schema tables had RLS disabled. Lovable did not flag this condition before launching apps. Developers who were not already familiar with Supabase's RLS model had no automated signal that their database was publicly accessible.
The complete remediation for CVE-2025-48757 is three steps in your Supabase SQL editor:
-- Step 1: Enable RLS on affected tables (repeat for every table) ALTER TABLE users ENABLE ROW LEVEL SECURITY; -- Step 2: Add owner-scoped SELECT policy -- Replace 'id' with the column that matches auth.users.id in your table CREATE POLICY "owner_only" ON users FOR SELECT USING (auth.uid() = id); -- Step 3: Verify no tables remain unprotected SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public' AND rowsecurity = false; -- Expected: zero rows returned
grep -r "service_role" ./dist ./public 2>/dev/nullSELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public' ORDER BY rowsecurity, tablename; -- rowsecurity = false → VULNERABLE (fix immediately) -- rowsecurity = true → check policies with Query 2
SELECT tablename, policyname, cmd, qual FROM pg_policies WHERE schemaname = 'public' AND qual = 'true'; -- Any result here = permissive policy (functionally equivalent to RLS off) -- Fix: ALTER POLICY to use USING (auth.uid() = user_id)
CVE-2025-48757 was documented in Lovable apps because they were the most prevalent AI-built app category in mid-2025. The vulnerability class is not Lovable-specific. Any app that:
...has the same exposure. This includes apps built with Bolt.new, Cursor, v0, Replit, and any custom ChatGPT or Claude-assisted development that generated Supabase schema migrations without RLS configuration.
As of June 2026, this remains the most common critical finding in vibe-coded apps scanned through Launch Ready Code. Average security score on first scan across all AI-built Supabase apps: 42/100.
URL-based scan. No code access. No signup. Checks RLS, service_role exposure, Edge Function auth, and 40+ additional vectors. Free Launch Readiness Score in 60 seconds.
Check if your app is affected — free scanCVE-2025-48757 is a class of misconfiguration documented in May 2025 affecting 170+ production apps. The root cause: Supabase tables have RLS disabled by default; AI builders scaffold schemas without enabling it; the Supabase anon key — public by design, in the client bundle — could therefore query any unprotected table and return all rows with no authentication. No login, no exploit required.
All apps that use Supabase and were built or scaffolded without manually enabling RLS. The original disclosure covered 170+ Lovable apps. The same pattern affects apps built with Bolt.new, Cursor, v0, Replit, and any AI-assisted development workflow that generated Supabase schemas without RLS configuration. Check your app: SELECT tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public'; — any false value means that table is exposed.
If you built with Lovable and have not manually enabled RLS on every table, you are likely vulnerable. Run the diagnostic SQL above in your Supabase SQL editor. Look for rowsecurity = false (any table is exposed) and qual = 'true' in your policies (permissive policies that provide no restriction). For a complete check including service_role exposure and Edge Function auth, run the free scanner at launchreadycode.com.
Three steps: (1) Enable RLS on every table: ALTER TABLE users ENABLE ROW LEVEL SECURITY; (2) Add owner-scoped policies: CREATE POLICY "owner_only" ON users FOR SELECT USING (auth.uid() = id); — replace any USING (true) policies with owner-scoped ones. (3) Check for service_role key in client code and rotate it if found. Test your app after each step to confirm legitimate access still works.
Lovable has increased RLS awareness in its interface since May 2025. The underlying issue is not a Lovable bug — it is a Supabase default (RLS off on new tables) combined with AI-generated schemas that did not enable it. Even with the latest Lovable version, you must verify RLS is enabled on every table in your production database. The fix is in your Supabase configuration, not in Lovable's code generator.
Sources: CVE-2025-48757 (NVD / Matt Palmer, May 2025); byteiota.com/supabase-security-flaw-170-apps-exposed-by-missing-rls; vibeappscanner.com/issues/supabase; Supabase documentation on Row Level Security. This page provides general security guidance and technical documentation, not a certification or guarantee.