Supabase Data Exposure: 16,326 Open Databases and the RLS Controls to Check
Security researchers at UpGuard reported on September 25, 2026 that they identified 16,326 Supabase databases exposing readable tables while studying roughly 300,000 domains with indicators of Supabase use. More than half of the exposed databases had schema indicators of personally identifiable information, while smaller subsets included password or authentication-token fields.
The finding is primarily an application-configuration problem. Supabase's current security documentation says tables and views exposed through its Data API require appropriate PostgreSQL grants and Row Level Security (RLS) policies. Tables created through the Supabase Dashboard have RLS enabled by default; tables created with SQL or other tooling require developers to enable it explicitly.
That distinction matters for AI-generated applications because coding agents commonly create database objects programmatically. A production audit should therefore verify the effective database controls instead of treating a generated application, publishable key or successful authentication flow as evidence that its tables are private.
What UpGuard measured
UpGuard assembled approximately 300,000 unique domains with Supabase indicators using technographic and public web datasets, then tested whether associated databases exposed readable tables. The researchers focused initially on a common users table and used returned schema information to characterize accessible data at scale.
The study identified 16,326 databases with readable tables. UpGuard says more than half contained indicators of PII. Its schema-level analysis also found smaller groups with password or authentication-token fields and a very small number with plausible payment-card data.
The researchers then manually investigated a limited set of higher-impact cases to confirm that real records were present and notified affected application owners. Examples described in the report include:
- an India-based adult-content platform with 65,467 user records containing identity and financial fields, plus more than 100,000 private messages;
- a Philippine OTP service exposing more than 100,000 SMS messages and account information;
- a U.S. valet service exposing more than 100,000 customer records, including license-plate and visit-history data;
- an African government consulate database containing 25,000 records with PII and physical-address information;
- a Canadian immigration and relocation service with nearly 5,000 user records, including 884 records containing plaintext passwords.
These cases are examples from the research population. They should not be interpreted as evidence that every Supabase project, every AI-generated application or every database in the 300,000-domain candidate set was exposed.
The Supabase security boundary
Supabase exposes PostgreSQL data through a Data API. Its documentation describes two controls that work together:
- PostgreSQL grants determine whether roles such as
anonandauthenticatedcan perform operations on a table, view or function. - RLS policies determine which rows those roles can access or modify.
Supabase's current API-security guide says existing projects may automatically grant SELECT, INSERT, UPDATE and DELETE privileges on new public tables to anon, authenticated and service_role. The platform is changing that default so exposure becomes opt-in. Those grants remain subject to RLS for roles that do not bypass it.
For tables exposed through the Data API, Supabase recommends enabling RLS and configuring grants for the minimum operations each role needs. A table in an exposed schema with RLS disabled can be accessible to a role that already has matching grants.
The creation path is therefore important. Supabase documents that the Dashboard Table Editor enables RLS by default. Tables created in the SQL Editor or through another tool require RLS to be enabled explicitly.
Audit every table created by an agent or migration
For an existing Supabase application, start with inventory rather than assumptions about how the schema was created. Review every table and view in schemas exposed through the Data API, especially objects introduced by migrations, scripts, MCP tools or coding agents.
For each exposed table, verify:
- RLS is enabled;
- policies exist for the intended
SELECT,INSERT,UPDATEandDELETEbehavior; anonandauthenticatedhold only the PostgreSQL grants the application requires;- tests cover both allowed and denied access paths;
- sensitive internal tables live outside exposed API schemas when direct client access is unnecessary.
Supabase's current RLS guide recommends pairing grants and policies and provides supabase test db for database policy tests. The guide specifically recommends testing operations for both anonymous and authenticated roles.
Check views and functions separately
Views and functions have additional authorization behavior that deserves a separate pass.
Supabase documents that PostgreSQL views commonly run with security definer behavior and can bypass the RLS policies of underlying tables. On PostgreSQL 15 and later, a view intended for client access can use security_invoker = true so the caller's permissions and RLS policies apply. Another option is to keep sensitive views in an unexposed schema and grant access deliberately.
RLS also does not govern function execution in the same way it governs table rows. Supabase recommends restricting EXECUTE grants and reviewing SECURITY DEFINER functions carefully. Its security guidance advises keeping privileged functions out of exposed schemas and pinning search_path where appropriate.
Publishable keys and service-role keys have different risk
A Supabase publishable key identifies the project and is designed for client-side use when database authorization is correctly configured. Supabase says the older anon key should be treated similarly: access still depends on database grants, RLS policies and the request's authentication context.
Service-role and secret keys are privileged credentials. Supabase's security documentation says they bypass RLS and must stay on trusted backend systems. A frontend bundle, public repository or generated client application containing one of those privileged keys creates a separate high-impact exposure path.
An incident review should therefore search deployed frontend assets, source repositories, CI logs and generated configuration for service-role or secret credentials. Rotate any privileged credential that has been exposed.
A practical remediation sequence
For teams using Supabase with Claude Code, Codex, Lovable, Replit or another code-generation workflow, a useful response sequence is:
- Inventory exposed schemas, tables, views and functions. Include objects created outside the Dashboard.
- Enable RLS on client-accessible tables and define explicit policies. Pair those policies with least-privilege grants.
- Test authorization as
anonandauthenticated. Include negative tests proving one user cannot read or modify another user's rows. - Review views and privileged functions. Apply
security_invokerwhere appropriate and keep internal objects outside exposed schemas. - Search for privileged keys. Rotate service-role or secret keys found in client code, repositories, logs or other untrusted locations.
- Use Supabase Security Advisors and database tests. Treat generated schema changes like application code: review and test them before deployment.
- Assess historical exposure. If sensitive data was publicly readable, preserve relevant logs, determine the exposure window, investigate access where telemetry permits and follow applicable incident-response and notification requirements.
This workflow is more durable than patching a single generated policy because authorization changes as schemas evolve. New migrations and agent-created tables need the same review gate.
Why AI-generated apps increase the operational risk
The underlying controls are standard PostgreSQL authorization mechanisms. The operational change is the speed and abstraction level at which schemas can now be created.
A coding agent can provision tables, APIs and frontend clients in one workflow. That reduces the number of points at which a developer naturally stops to inspect database grants and policies. UpGuard's research specifically broadened prior studies beyond named vibe-coding platforms to include standalone sites that could have been built with general coding agents such as Claude Code and Codex.
The appropriate engineering response is to make authorization verification part of the deployment pipeline. RLS state, grants, policy tests, exposed schemas and privileged-key scans can all be checked independently of who or what generated the application code.
Bottom line
UpGuard's 16,326-database result shows that Supabase authorization mistakes can exist at meaningful scale across real applications. The research identifies configuration as the recurring failure mode, while Supabase says its projects are secure by default and describes security as a shared responsibility in which customers control project configuration.
For operators, the actionable boundary is clear: inventory every Data API object, verify RLS and grants together, test deny paths, review views and privileged functions, and keep service-role credentials on trusted backend systems. AI-generated database changes should pass those checks before production deployment.
Sources
- UpGuard Research — Everything Everywhere: Systemic Data Exposure in Supabase Apps: https://www.upguard.com/blog/everything-everywhere-systemic-data-exposure-in-supabase-apps
- Supabase — Securing your API: https://supabase.com/docs/guides/api/securing-your-api
- Supabase — Row Level Security: https://supabase.com/docs/guides/database/postgres/row-level-security
- Supabase — Securing your data: https://supabase.com/docs/guides/database/secure-data
- TechCrunch — Some Supabase customers are publicly exposing reams of people's data to the web: https://techcrunch.com/2026/09/25/some-supabase-customers-are-publicly-exposing-reams-of-peoples-data-to-the-web/