Supabase has strong security primitives — Row Level Security, role-based access, fine-grained policies. The problem is that AI coding tools skip the configuration step. 68% of Supabase-backed apps we tested had missing or broken access controls. The platform is not the issue. The setup is.
Supabase's security model works — when it is configured. The anon key is safe to expose when RLS is on. PostgREST is safe when policies restrict access. The gap is between what Supabase provides and what AI tools actually set up.
The single most common vulnerability in Supabase apps built with AI tools. RLS is disabled by default on new tables. AI code generators create tables without enabling it. The result: full database access via the anon key.
68% of apps using Supabase or Firebase backends had missing or broken access controls in our 100-app study. CVE-2025-48757 confirmed this pattern across 170+ Lovable apps with 303 exploitable endpoints.
The Supabase service_role key bypasses all RLS policies. It should only exist on your server. AI tools sometimes import it in client-side components or store it with a NEXT_PUBLIC_ prefix, making it visible in the browser.
Unlike the anon key, which is designed to be public, the service_role key is a full-access master key. Exposing it means RLS provides zero protection — even properly configured policies are bypassed entirely.
Supabase exposes a PostgREST API at /rest/v1/ that maps directly to your database tables. With the anon key and no RLS, an attacker can query any table, filter any column, and paginate through your entire dataset using standard REST calls.
The PostgREST API is powerful by design — it auto-generates endpoints for every table. This is a feature when RLS is properly configured. Without RLS, it is an open database API that anyone with your anon key can use.
Having RLS enabled is necessary but not sufficient. AI-generated policies sometimes use USING (true) or allow operations the app does not need. A policy that allows SELECT for all authenticated users might expose data that should be restricted to the owning user.
Lovable shipped a security scanner that checked whether RLS was enabled but did not validate whether policies were actually restrictive. A policy like "allow all authenticated users to read all rows" passes that check while providing no real protection.
Yes — if and only if RLS is properly configured. The Supabase anon key is a JWT with the anon role claim. It is designed to be in your client-side JavaScript. Supabase's documentation explicitly says so. The key authenticates requests to the PostgREST API, and RLS policies determine what those requests can access.
When RLS is enabled with proper policies, the anon key can only access data the policies allow — typically public content or the authenticated user's own rows. When RLS is disabled, the anon key grants unrestricted read and write access to the entire table. Same key, opposite security posture, depending on one database setting.
The service_role key is different. It bypasses all RLS policies entirely. It should only exist in server-side code — never in client bundles, never with a NEXT_PUBLIC_ prefix, never in a Vite client module. If you search your deployed JavaScript for "service_role" and find it, that is a critical vulnerability regardless of your RLS configuration.
No. The same pattern applies to every Backend-as-a-Service platform. Firebase has Security Rules. Supabase has RLS policies. Both are opt-in. Both default to open during development. Both depend on the developer (or the AI) configuring them before production.
In the Firebase ecosystem, researchers scanned five million domains and found 900+ sites with completely open databases — exposing approximately 125 million user records including 19 million plaintext passwords. Different platform, same root cause: security configuration left in test mode.
The lesson is platform-agnostic: any backend that puts security configuration in the developer's hands will have this problem at scale. AI coding tools amplify it by generating apps faster than developers can review security settings.
Flowpatrol tests your Supabase configuration from the outside — the same way an attacker would find these issues.
Finds anon keys and service_role keys in your JavaScript bundles. Flags the service_role key as critical if present client-side.
Uses discovered credentials to attempt unauthenticated and cross-user data access against the PostgREST API. Reports exactly which tables are exposed.
Goes beyond "is RLS enabled" to test whether policies actually restrict access correctly. Checks for overly permissive policies and missing write restrictions.
A deep dive into Row Level Security — what it is, how to configure it, and why AI tools keep skipping it.
CVE-2025-48757 case study — how missing RLS on Lovable-generated Supabase apps exposed 303 endpoints.
900+ sites, 125 million records, 19 million plaintext passwords. Same BaaS pattern, different platform.
The most common security issues we find in vibe-coded apps, with real examples and fixes.
Paste your URL. Find out if your RLS is actually working before someone else tests it for you.