Chupabase tool exploits misconfigured Supabase RLS in Lovable-generated apps to extract data without authentication
Hakai Security released Chupabase, a Python tool that finds and demonstrates insecure Supabase backend configurations in applications generated by the vibe coding platform Lovable. It parses the app's JavaScript bundles (and the sw.js Service Worker precache manifest) to recover the Supabase URL, the public anonKey and the API endpoint map. It then probes which tables, RPCs and Edge Functions respond to the anon role. In preliminary tests the authors found several apps exposing user data, logs and form records. The article ties the issue to CVE-2025-48757, reported by researcher Matt Palmer, which exposed data from more than 170 Lovable-generated apps because Row Level Security (RLS) policies were missing or misconfigured. Lovable's position is that each customer is responsible for securing their own app's data.
Technical Details
- The anonKey is a role identifier, not a secret. The weakness is excessive permissions for the
anonrole: RLS disabled or permissive on PostgREST tables, RPCs running asSECURITY DEFINERor executable byanon, and Edge Functions without JWT validation. - The attacker model is an unauthenticated external user who needs only the public frontend and its static files.
- Chupabase runs in 6 steps: (1) find
sw.jsand its precached assets, (2) locate the largest.jsbundle, (3) extract the Supabase URL and anonKey, (4) scan for.from(),.rpc()calls and Edge Function URLs, (5) generate aswagger.yaml, (6) with the test flag, check which endpoints return 200 OK under theanonrole. - Default Lovable stack: React, Vite, Tailwind, shadcn/ui, with Supabase/PostgreSQL as the backend.
- In a well-configured app the tool should only see 401/403 responses.
Remediation
- Enable RLS on all tables and use
ALTER TABLE <name> FORCE ROW LEVEL SECURITY. - Add
TO authenticatedto policies for non-public data, and base policies onauth.uid()orauth.jwt(). - Validate
auth.role() = 'authenticated'inside RPCs and keep themSECURITY INVOKER. RunREVOKE EXECUTE ON FUNCTION <function_name>() FROM anonfor sensitive functions. - Verify the JWT explicitly in Edge Functions, for example with
supabase.auth.getUser(). - Move critical tables out of the
publicschema, apply least privilege to theanonrole, and audit production bundles and the Service Worker regularly.
Linha do tempo
-
Chupabase tool exploits misconfigured Supabase RLS in Lovable-generated apps to extract data without authentication
ler a análise desta fonte ocultar
Hakai Security released Chupabase, a Python tool that finds and demonstrates insecure Supabase backend configurations in applications generated by the vibe coding platform Lovable. It parses the app's JavaScript bundles (and the
sw.jsService Worker precache manifest) to recover the Supabase URL, the public anonKey and the API endpoint map. It then probes which tables, RPCs and Edge Functions respond to theanonrole. In preliminary tests the authors found several apps exposing user data, logs and form records. The article ties the issue to CVE-2025-48757, reported by researcher Matt Palmer, which exposed data from more than 170 Lovable-generated apps because Row Level Security (RLS) policies were missing or misconfigured. Lovable's position is that each customer is responsible for securing their own app's data.Technical Details
- The anonKey is a role identifier, not a secret. The weakness is excessive permissions for the
anonrole: RLS disabled or permissive on PostgREST tables, RPCs running asSECURITY DEFINERor executable byanon, and Edge Functions without JWT validation. - The attacker model is an unauthenticated external user who needs only the public frontend and its static files.
- Chupabase runs in 6 steps: (1) find
sw.jsand its precached assets, (2) locate the largest.jsbundle, (3) extract the Supabase URL and anonKey, (4) scan for.from(),.rpc()calls and Edge Function URLs, (5) generate aswagger.yaml, (6) with the test flag, check which endpoints return 200 OK under theanonrole. - Default Lovable stack: React, Vite, Tailwind, shadcn/ui, with Supabase/PostgreSQL as the backend.
- In a well-configured app the tool should only see 401/403 responses.
Remediation
- Enable RLS on all tables and use
ALTER TABLE <name> FORCE ROW LEVEL SECURITY. - Add
TO authenticatedto policies for non-public data, and base policies onauth.uid()orauth.jwt(). - Validate
auth.role() = 'authenticated'inside RPCs and keep themSECURITY INVOKER. RunREVOKE EXECUTE ON FUNCTION <function_name>() FROM anonfor sensitive functions. - Verify the JWT explicitly in Edge Functions, for example with
supabase.auth.getUser(). - Move critical tables out of the
publicschema, apply least privilege to theanonrole, and audit production bundles and the Service Worker regularly.
- The anonKey is a role identifier, not a secret. The weakness is excessive permissions for the