CVE-2025–48757 - what happened, why it still matters, and how to check your fleet
A technical deep-dive for security teams and engineers
TL;DR
CVE-2025–48757 is an insufficient/incorrect authorization issue stemming from missing or weak Row-Level Security (RLS) policies in databases provisioned by the Lovable AI builder. In many cases, Lovable-generated projects left databases exposed so that unauthenticated remote requests could read from or write to arbitrary tables. The root cause is a platform-level failure: defaulting to insecure configurations and failing to validate RLS semantics, not a flaw or zero-day in Postgres itself. While the vulnerability is not new, variants of it continue to be observed today - insecure RLS configurations remain a recurring problem in AI-driven builder platforms. These exposures have high impact on enterprises, where a single misconfigured project can lead to broad unauthorized access, data leakage, and compliance violations across critical environments.
1) Quick background: Lovable
Lovable is an AI-driven “vibe-coding” builder that generates full-stack projects (frontend + backend + DB) from natural language prompts. It provisions hosting and databases for generated sites and aims to minimize developer friction. That convenience is why many apps are created with it.
2) Quick background: Supabase
Supabase is a hosted Postgres + realtime + auth stack that many low-code/no-code builders adopt as the database backend. Supabase exposes a REST/GraphQL API and includes Postgres Row-Level Security (RLS) as a primary mechanism for enforcing per-user data access at the DB layer. Supabase docs explicitly recommend enabling and writing RLS policies so client-side code (browsers, public API keys) cannot read or write data they shouldn’t.
3) How Lovable and Supabase typically interact
A typical flow:
Lovable provisions a Postgres database (Supabase) for the generated app.
The generated frontend uses a client key (sometimes a public anon key) to call Supabase APIs directly from the browser/mobile client.
Authorization/identity is intended to be enforced by combining Supabase Auth (or JWTs) and RLS policies inside Postgres.
If RLS is missing, insufficient, or incorrectly configured, a public API key + crafted queries/requests can often enumerate or mutate rows across tables. CVE-2025–48757 is an instance where platform defaults or checks allowed unsafe combinations to reach production.
4) Row-Level Security (RLS) - what it is and how to configure it
What RLS does - RLS is a Postgres primitive that evaluates a boolean expression for each row and each operation (SELECT/INSERT/UPDATE/DELETE). If the expression evaluates to true, the operation is allowed on that row; otherwise it’s blocked. Combined with per-user identity (JWT claims), it enforces per-row access rules at the database level. Supabase exposes and encourages RLS for authorization. When configured currently - this allows very strong authorization for an app.
A basic example in Supabase - profiles table where each row has user_id:
-- enable RLS for the table
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;-- policy: allow a logged-in user to SELECT their own profile
CREATE POLICY “profiles_select_own”
ON public.profiles
FOR SELECT
USING (user_id = auth.uid());-- policy: allow a logged-in user to UPDATE their own profile
CREATE POLICY “profiles_update_own”
ON public.profiles
FOR UPDATE
USING (user_id = auth.uid())
WITH CHECK (user_id = auth.uid());Notes:
auth.uid() is the Supabase helper that maps the current JWT’s sub to a Postgres value at runtime.
USING controls which rows are visible for reads; WITH CHECK validates row contents on write.
For functions, triggers, or server-side jobs you may need SET LOCAL role tricks or secure function patterns to bypass RLS when legitimately required. See Supabase docs for advanced patterns.
Common RLS pitfalls to avoid
Relying only on client code -never trust that the front end will enforce authorization.
Using permissive policies like USING (true) for convenience.
Leaving public/anonymous API keys able to read sensitive tables because no RLS policy exists.
Thinking “RLS exists so we’re safe” - but policies need to be correct; a policy that compares to a wrong claim or a global flag can be bypassed.
5) What CVE-2025-48757 really is
Lovable-generated projects sometimes ended up with insufficient or incorrectly scoped RLS policies on their Supabase Postgres instances. That meant requests crafted against Lovable-provisioned endpoints could read or write tables without per-row authorization checks. The vulnerability is an incorrect authorization / insufficient RLS condition - not a Postgres engine bug.
Attack path
Lovable provisions a Supabase DB and exposes an application endpoint that uses a public anon key (or insufficiently scoped key).
The generated frontend assumes RLS or relies on a “has RLS been enabled” flag, but the actual policies are missing, too permissive, or incorrectly express identity checks.
An unauthenticated remote attacker crafts API calls (or manipulates the REST paths the generated site uses) to enumerate or mutate rows in arbitrary tables because the DB enforced no per-row restrictions.
Sensitive columns (PII, tokens, secrets, internal flags) are exfiltrated or altered. In some reported incidents, attackers used sites created on Lovable to host phishing or malware content - the lack of DB enforcement makes it trivial to escalate and pivot.
This was indeed observed at scale in the wild, exposing hundred of apps data. Lovable and some vendors argue that customers still hold responsibility for configuring RLS correctly for their apps.
6) Why CVE-2025–48757 Still Matters Today
Although Lovable and other builder platforms have improved their default configurations since the original disclosure, CVE-2025–48757 remains highly relevant today. Pluto’s real-world scans consistently show that the most common vulnerability across AI-generated builder projects is incorrect or incomplete Row-Level Security (RLS) configuration. Even when RLS is enabled by default, developers frequently misapply or override policies, unintentionally leaving tables exposed. As a result, many live sites still operate with overly permissive database permissions, allowing unauthorized reads or writes across user data. With the rapid expansion of AI-built apps and prototypes, these misconfigurations scale quickly - creating widespread exposure across hundreds of interconnected websites and services.
7) Detection & remediation steps
Inventory -Find your vibe-coded apps, look for DNS requests for supabase to see what users configured one. The code will hold the supabase.co domain, Any app using Supabase should be reviewed.
Scan and fix - Run Lovable Security Advisor, It integrates with Supabase RLS Advisor to detect missing RLS policies. Don’t trust it blindly - review each suggested policy; it often makes mistakes or uses over-permissive rules.
Manually verify RLS in Supabase - In Supabase SQL editor, check for tables without RLS:
SELECT schemaname, tablename
FROM pg_tables
WHERE schemaname = ‘public’
AND tablename NOT IN (
SELECT tablename FROM pg_policies WHERE schemaname=’public’
);Enable RLS and apply strict policies if missing:
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;
CREATE POLICY “profiles_select_own”
ON public.profiles FOR SELECT
USING (user_id = auth.uid());Confirm anon and public roles have no direct table access:
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM anon, public;Final notes
RLS is powerful but brittle if used incorrectly - it must be tested, audited, and enforced as part of platform provisioning.
If you operate or rely on any “AI builder” security, assume they can be unsafe. You own the responsibility for what you are building.
At Pluto - we are enabling usage of AI Builders securely in enterprises. Want to learn more? Lets talk!
Additional context & references
Matt Palmer’s public statement and analysis
CVE entry for CVE-2025–48757
Supabase official docs on RLS





