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 issue in Supabase apps built with AI tools. Per-user access rules (Row Level Security, or RLS) are off by default on new tables. AI code generators create tables without turning them on. The result: full database access via the public 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 open endpoints.
The Supabase `service_role` key skips every access rule — it is the master key. It should only exist on your server. AI tools sometimes import it in frontend components or store it with a `NEXT_PUBLIC_` prefix, which ships it straight to the browser.
Unlike the public key, which is designed to be public, the `service_role` key is full read/write on everything. If it leaks, RLS buys you nothing — even perfect per-user rules get skipped.
Supabase auto-generates a REST API (PostgREST) at `/rest/v1/` that maps every table, column, and filter to standard HTTP calls. With the public key and no per-user rules, anyone can query any table, filter by any column, and paginate through your entire dataset from a browser.
The API layer is powerful by design — it is a feature when per-user rules are on. Without them, it is an open database any visitor can read with `curl`.
Having per-user rules turned on is necessary but not enough. AI-generated rules sometimes use `USING (true)` or allow actions the app does not need. A rule like "any logged-in user can read any row" technically counts as "RLS is on" while leaking everything.
Lovable shipped a security scanner that checked whether RLS was on but never checked whether the rules actually restrict anything. 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.
How the same BaaS default shipped to production in Moltbook, Tea, Cal AI, and Quittr.
Paste your URL. Find out if your RLS is actually working before someone else tests it for you.