CVE-2025-48757 explained: open Supabase tables in Lovable apps, and how to check yours
Short answer: CVE-2025-48757 is about Lovable-built apps whose Supabase tables had Row Level Security (RLS) that was missing or too loose. Those apps call the database straight from the browser with the public anon key, so RLS is the only thing between a stranger and the data. If a table isn't covered, anyone can read it, and sometimes write to it. The fix is to turn RLS on for every exposed table and write policies that limit rows to their owner. To see whether your own live site lets signed-out visitors read a table, run a free SniffPup scan (SniffPup is a free passive security scanner for vibe-coded apps) and look for the CVE-2025-48757 check label. Only check sites you own.
Home › Guides › CVE-2025-48757 · Last updated · By Ember, SniffPup
The fast way: a free SniffPup scan runs 15 checks from the outside, including the CVE-2025-48757 check: it uses the public Supabase key your site already ships and asks whether a signed-out visitor can read rows. No signup, and no rows are downloaded.
A 100 means no issues were found in our checks. It is never proof of security.
1. What the CVE record says
From the NVD entry (also on CVE.org), published May 29, 2025:
"An insufficient database Row-Level Security policy in Lovable through 2025-04-15 allows remote unauthenticated attackers to read or write to arbitrary database tables of generated sites."
- Weakness: CWE-863, Incorrect Authorization.
- Score on the record: CVSS 3.1 9.3, Critical (from MITRE):
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:L/A:N. NVD has not added its own score. The researcher's write-up gives 8.26. - Disputed: the record notes that Lovable disputes it, "because each individual customer of the Lovable platform accepts a responsibility over protecting the data of their application."
2. What the researcher found
The issue was found by Matt Palmer, with Kody Low, who published a technical write-up and a statement with the disclosure timeline. In short:
- Lovable apps make REST calls to the database directly from the browser using the public, unprivileged anon key, and rely on RLS alone to keep data private.
- Where a table had missing or insufficient policies, changing the request (for example asking for
?select=*) returned rows the visitor shouldn't see. The write-up says the exposed data included personal details and API keys for other services, and that some projects also accepted writes. - Timeline from the write-up: discovered March 20, 2025, Lovable notified March 21, another engineer independently posted about the same issue on April 14, and the CVE was published May 29, 2025. Lovable released a security scan feature on April 24, 2025; the researchers' view is that it didn't change the underlying design.
The record names projects created up to April 15, 2025, but the write-up says later projects may be affected too. Whatever tool you built with, the safe assumption is to check your own tables.
3. How to fix it in Supabase
Supabase's RLS guide says to enable RLS on every table in an exposed schema (public by default): a table there without RLS is readable and writable by any role with a grant on it. The anon key is meant to be public (see API keys), so your policies do the protecting.
- Turn RLS on for every table in
public. The researcher's write-up notes that tables made in the Supabase Table Editor have it on by default, while tables made with SQL need it turned on by hand.alter table public.profiles enable row level security;
- Write owner-only policies instead of ones that allow everyone, such as
using (true)on private data:create policy "Users can view their own profile" on public.profiles for select to authenticated using ( (select auth.uid()) = user_id );
Add matchinginsert,updateanddeletepolicies only where users really need them, withwith checkon writes. - Keep public tables public on purpose. If something really is meant for everyone (a product list, say), allow
selectonly, and keep private columns in a separate table. - Find tables with RLS off in the SQL editor:
select c.relname as table_name from pg_class c join pg_namespace n on n.oid = c.relnamespace where n.nspname = 'public' and c.relkind = 'r' and not c.relrowsecurity order by 1;
- Check from the outside with the anon key only. A signed-out request should get no rows from private tables:
curl -s "https://YOUR-PROJECT.supabase.co/rest/v1/profiles?select=id&limit=1" \ -H "apikey: YOUR_ANON_KEY"
An empty list ([]) for a table with data means RLS is blocking it. Supabase's Securing your API page covers more.
If a table was open and held personal data or keys, replace any keys that were stored there and think about who may need to be told. More policy patterns: Supabase RLS policy examples and is the Supabase anon key safe?
4. What SniffPup's CVE-2025-48757 check does, and doesn't, test
Findings that test this behaviour carry a CVE-2025-48757 check label in your report. Here is exactly what runs:
- Free scan: if your site's public code includes a Supabase URL and anon key, we ask your API which tables it lists, then for up to 8 of them send one read-only request that only answers "is at least one row readable?". No rows are downloaded.
- Pro deep check (sites you've verified you own): up to 30 tables over the REST API with row counts, plus count-only GraphQL queries. Still no row contents kept.
What it doesn't test:
- Writes. We never insert, change or delete anything, so we can't confirm the "write" half of the CVE. (The deep check does tell you when your GraphQL schema offers write operations to signed-out visitors, without running any.)
- Signed-in access. We test as a signed-out visitor, so a policy that lets any logged-in user read everyone's rows won't show up.
- Tables your API doesn't list, empty tables, and tables past the limits above.
FAQ
What is CVE-2025-48757?
A CVE record published on May 29, 2025. Its description reads: "An insufficient database Row-Level Security policy in Lovable through 2025-04-15 allows remote unauthenticated attackers to read or write to arbitrary database tables of generated sites." It is classed as CWE-863, Incorrect Authorization.
Is CVE-2025-48757 disputed?
Yes. The record carries a note that the supplier disputes it, because each Lovable customer accepts responsibility for protecting their own app's data. NVD tags it disputed.
How severe is it?
The score on the record, from MITRE, is CVSS 3.1 9.3 (Critical): network attack, low complexity, no privileges or user interaction needed. The researcher's own write-up scores it 8.26. NVD has not added a separate score of its own.
Does it only affect Lovable apps?
The CVE is about Lovable. The mistake behind it isn't unique to one tool, though: any app whose browser code talks to Supabase with the public key relies on Row Level Security, so a table with RLS off or a policy that allows everyone is open in the same way.
What does SniffPup's CVE-2025-48757 check test?
Signed-out reads only. With the public Supabase key your site already ships, the free scan asks your API which tables it lists and, for up to 8 of them, whether an anonymous visitor can read at least one row. It downloads no rows. The Pro deep check on a verified site goes further with row counts over REST and GraphQL. It never sends writes, so it can't tell you whether strangers can add, change or delete rows.
If my scan has no CVE-2025-48757 findings, am I safe?
Not necessarily. It means no signed-out reads turned up in the tables we checked. It is never proof of security: we don't test writes, policies that let any signed-in user see everyone's rows, or tables your API doesn't list. Review your policies in Supabase too.
Sources: NVD: CVE-2025-48757, CVE.org record, Matt Palmer's write-up and statement; Supabase Row Level Security, Securing your API and API keys docs. Checked October 31, 2026.
A score of 100 means no issues were found in our checks. It is not proof that your app is secure.