16,326 Supabase databases left readable to anyone
UpGuard found 16,326 Supabase databases with tables anyone could read, most holding personal data. How missing RLS causes it and the exact checks to run.
By Yaali. October 4, 2026, 6 min read, Cloud, AI security.
UpGuard published research on September 25 showing 16,326 databases hosted on Supabase that answered queries from anyone on the internet. The researchers started from about 300,000 domains whose public JavaScript carried Supabase key names and database addresses, and asked each one for its tables. More than half of the readable databases had signs of personal data. A smaller share held passwords or authentication tokens, and a very small number held what looked like credit card data.
Supabase itself was not breached. Each exposed project belonged to a customer who shipped tables without working row level security (RLS), and in many cases the app was built quickly with an AI coding agent. UpGuard does not claim that every affected app was AI-built. If your product talks to Supabase from a browser or mobile app, you can check your own project in about ten minutes.

How a Supabase table ends up public
Supabase puts an automatic REST interface, the Data API, in front of the Postgres database. A frontend calls https://<project-ref>.supabase.co/rest/v1/<table> and passes the project's public key, the legacy anon key or the newer sb_publishable_ key. That key is meant to be public: it ships in every page load, and anyone can copy it from the browser's network tab. Requests made with it run as the Postgres role anon, or authenticated once a user signs in.
Two checks are supposed to stand between that public key and your rows. Grants decide whether a role may run select, insert, update or delete on a table at all. RLS policies then decide which rows the role sees. Supabase's documentation says that on existing projects a new table in public starts with all four privileges granted to anon and authenticated. If RLS is off, nothing else filters the rows, and the Security Advisor rates this as an error: anyone with the project URL can read, edit and delete every row.
Tables created in the Supabase dashboard's Table Editor get RLS switched on by default. Tables created with SQL, migrations or other tooling do not, and UpGuard points out that this is the route coding agents use. An agent asked to "add a users table" writes create table, the app works in the demo, and nobody notices that the table also answers strangers.
The other failure UpGuard and later reporting describe is misuse of keys. RLS can be on and still mean nothing if a policy reads using (true) for anon, or if a view created by the postgres user exposes the table underneath, since Postgres views bypass RLS by default. Worse, some apps ship the service_role key, or its replacement sb_secret_ key, in client code. That key maps to a role with the BYPASSRLS attribute, so every policy is skipped.
The pattern is not new. In 2025 the same RLS gap in apps generated with Lovable was assigned CVE-2025-48757, rated 9.3 under the Common Vulnerability Scoring System (CVSS), after a researcher found exposed tables in 170 of 1,645 apps scanned.
What the exposed data looked like
UpGuard queried each candidate for a table called users and sorted the answers into three groups: access refused, no users table but other readable tables, or rows returned. It then looked at a handful of exposures in detail and notified the owners. One service for immigration paperwork held about 4,900 user records, 884 of them with passwords stored in plain text. A valet company exposed more than 100,000 customer records with phone numbers and license plates. A consular database held personal details and physical addresses for 25,000 people, and a one-time passcode service exposed more than 100,000 SMS messages containing the codes.
Supabase's chief information security officer, Bil Harmer, told TechCrunch that security is a shared responsibility and that customers control how their own projects are configured. Supabase is already changing the default. Since May 30, 2026, new projects no longer expose new tables in public to the Data API until someone grants access, and on October 30 the same rule applies to all existing projects. Supabase's changelog is clear that existing tables keep their current grants, so this change does nothing for tables that are readable today.
What to do

Run the Security Advisor. In the dashboard open Advisors, then Security Advisor, or run
supabase db advisorswith the CLI. Treat0013_rls_disabled_in_publicand0023_sensitive_columns_exposedas incidents. Also read0024_permissive_rls_policy, which flagsusing (true), and0010_security_definer_view.List every table without RLS yourself in the SQL Editor:
select schemaname, tablename from pg_tables where schemaname = 'public' and rowsecurity = false;Repeat for any other schema listed under Exposed schemas in your API settings. To find always-true policies, run
select tablename, policyname, roles, cmd from pg_policies where qual = 'true' or with_check = 'true';.Enable RLS and trim grants for each table:
alter table public.<table> enable row level security;, thenrevoke all on table public.<table> from anon, authenticated;and grant back only what each role needs. With RLS on and no policies, the publishable key sees nothing, which is the safe failure. Then write one policy per operation, for exampleusing ((select auth.uid()) = user_id).Fix views. On Postgres 15 and later, set
security_invoker = trueon any view in an exposed schema so it obeys the caller's policies.Stop new tables arriving open. Supabase documents an event trigger that runs
alter table ... enable row level securityon every new table inpublic, andalter default privileges for role postgres in schema public revoke select, insert, update, delete on tables from anon, authenticated, service_role;to remove automatic grants.Keep the secret key on the server. Search your frontend bundle, mobile builds and Git history for
service_role,sb_secret_and any long key starting witheyJused outside server code. Move to publishable and secret keys: Supabase is deprecating the legacyanonandservice_rolekeys by the end of 2026, and a secret key sent from a browser is rejected with HTTP 401.Rotate anything that leaked. Under Settings, then API Keys, create a new secret key, deploy it everywhere, confirm nothing still uses the old one, then delete it. Legacy keys are deactivated in the same screen. Rotate any third-party tokens stored in a table that was readable.
Checking whether someone already read your data
Test from outside first: curl "https://<project-ref>.supabase.co/rest/v1/users?select=*&limit=1" -H "apikey: <publishable key>" should return an empty list or a permission error, never a row.
Then look at the API Gateway logs. In Explorer, choose the Logs source and run:
select log_attributes['request.headers.cf_connecting_ip'] as ip,
log_attributes['request.path'] as path, count() as hits
from logs
where source = 'edge_logs' and log_attributes['request.path'] like '/rest/v1/%'
group by ip, path order by hits desc limit 200;
Large reads of whole tables, or requests for table names your app never calls, from addresses that are not yours, point to scraping. Log retention depends on your plan, so export what you have now. If personal data or plaintext passwords were readable, treat it as a breach: force password resets, hash passwords properly, and check your notification duties.
Generated code needs a security review
A coding agent will produce an app that works long before it produces one that is safe, and a table that answers every visitor still works in a demo. Every migration an agent writes needs the same review a junior developer's would get, with RLS and grants checked before release.
Our cloud and Kubernetes security reviews cover Supabase grants, policies and key handling, and our web application penetration testing checks what an anonymous visitor can pull through your API. To have someone look at your project, open the chat and Yaali, our AI agent, will pass your question to an engineer.
Sources: UpGuard, TechCrunch, Cybernews, Unite.AI, The IT Nerd, Privacy Guides, Aviatrix Threat Research Center, Supabase changelog, Supabase RLS docs, Supabase API keys docs, Supabase Advisors docs, Supabase log fields, SecurityOnline on CVE-2025-48757.
Read next
- GitLab AI Gateway flaw: a custom flow can run commands
- Unsloth Studio ran model code on a config check
- Google: CVEs doubled in 2026 and AI finds riskier flaws
Back to the blog, or tell us about your system in the chat. Yaali, our AI agent, answers first and brings in an engineer.