What happened

UpGuard's Greg Pollock built a list of about 300,000 domains using two sources: BuiltWith technology fingerprints and the Chrome UX Report dataset, filtered by Supabase key names and database addresses visible in public JavaScript files. For each, the researchers checked whether the public (anonymous) key a site already hands to every visitor could read a users table or other data.

16,326 databases could. UpGuard reports that more than half showed indicators of personally identifiable information, a smaller percentage exposed passwords or authentication tokens, and a very small number showed signs of payment card data. Examples it published, without naming the companies:

  • A US valet service: more than 100,000 customer phone numbers, about 43,000 names and emails, and 78,000 licence plates.
  • A Canadian immigration service: nearly 5,000 records, 884 of them with plaintext passwords.
  • An African government consulate: 25,000 people's personal data, including emergency housing locations.
  • A Philippines one-time-password service: more than 2,000 users and over 100,000 SMS messages containing OTP codes.
  • An Indian adult content platform: 65,467 user records including identity documents and financial details, and more than 100,000 private messages.

The root cause UpGuard describes is a gap between two defaults. Supabase turned on Row Level Security by default in 2025 for tables created in its Table Editor, but tables created programmatically through the API do not get it by default, and AI coding agents create tables that way. BleepingComputer, reporting the study on September 28, summarises the causes as missing or ineffective row-level security policies and misuse of public keys.

Why it matters if you run public infrastructure

This is the 2020s version of the open S3 bucket, and UpGuard makes that comparison itself. The database is not on your server, it does not listen on a port you own, and its address and key are meant to be public. Whether the data behind them is private depends entirely on policies inside the database. A firewall review, a port scan of your hosts or a penetration test scoped to your domains will pass cleanly while every row is readable.

It also shows how the attack surface has moved. UpGuard links the pattern to AI coding agents, which create tables through the API, and to people building applications through those agents without knowing how the database behind them is configured. In that setup the security decision is made by whatever generated the SQL, and often nobody reviews it.

What to check this week

  1. Find every Supabase project your organisation uses, including ones built by marketing, product experiments and contractors. Search your front-end bundles for supabase.co URLs and anon keys; that is exactly how UpGuard found them.
  2. Check Row Level Security on every table in exposed schemas, especially tables created by migrations or agents rather than the dashboard. RLS enabled with no policy denies access; RLS disabled allows it.
  3. Test as an outsider. Use the anon key from your own public site and try to read each table. If you get rows you did not mean to publish, so can anyone.
  4. Run Supabase's own security advisors and read its API security guidance, as BleepingComputer's report recommends.
  5. Add an RLS check to code review for any change an AI agent makes to the schema. The agent will not ask.

How Attack Surface Scan covers this

Honestly, it does not see this class of exposure. Attack Surface Scan scans hosts under domains you have verified and never logs in, queries an API with a key, or connects to cloud or database accounts (see How scanning works). A Supabase project lives on Supabase's infrastructure, and whether its tables are readable is a policy question that only a request made with the project's key can answer.

What it does cover is the older version of the same mistake on infrastructure you run: a database port such as PostgreSQL on 5432 or Elasticsearch on 9200 answering from the internet on one of your hosts is a high-severity finding, and a high-severity port that starts answering is sent to your alert channels immediately (see Exposed services and ports). The inventory also lists hosts that point into a SaaS platform by CNAME as dependencies, never scanned, which helps answer "which outside platforms do we run on?" (see Asset inventory). For Supabase itself, the checklist above is the control.

Sources