Security basics
Can anyone read your Supabase database? We checked 3,680 apps
Can anyone read your Supabase database without logging in? We scanned 30,998 live apps built with AI builders and measured how often the answer is yes.
In short
- Can anyone read your Supabase database without logging in? For 2,096 of the 3,680 apps where we could complete the check (57%), at least one table said yes.
- That is not automatically a leak. Some tables are meant to be public. But 394 of those apps had an open table named after people: users, profiles, customers, orders.
- The thing owners are usually warned about, a secret key sitting in the app, turned up 3 times in 30,998 apps. The open table is the common one.
Your app has a login screen. Behind it sit your users, their messages, maybe their orders. It looks private, and there is no obvious way to find out whether it actually is, because the Supabase console is not somewhere you have ever needed to go.
So we went and measured it on other people's apps. In August 2026 we scanned 30,998 live apps published from Lovable, Base44, Replit, v0 and Bolt, and asked one question of each: can anyone read your Supabase database without logging in?
For 2,096 of the 3,680 apps where we could get a straight answer, yes.
Here is the part that both the alarming version of this story and the reassuring one get wrong. An open table is not automatically a leak. Plenty of tables are meant to be read by everyone. Which table it is decides everything, and that is a question only the person who built the app can answer. It is also why nobody catches this: the app works perfectly either way.
Can anyone read your Supabase database?
For more than half of the apps we could check, yes: at least one table returned rows to a request carrying no login at all.
The reason this is possible has nothing to do with anything being broken. Your app talks to Supabase from your visitor's browser, so it carries a key that every visitor can read, and that key is meant to be public. It names your project. It grants nothing by itself.
What decides whether a stranger gets your data is Row Level Security: a rule on each table saying who may read which rows. With no rule, the key is the only thing standing between the internet and that table, and the key is written in your page.
That is what we were measuring. Not whether a key was visible (it always is), but what the database does when somebody uses it.
What the 57% is a share of
It is a share of a base we narrowed three times, and the narrowing matters more than the headline.
| What we counted | Apps |
|---|---|
| Live apps scanned and classified | 30,998 |
| Named a Supabase project in the page | 8,435 |
| Where we could confirm a table and get an answer | 3,680 |
| At least one table readable with no login | 2,096 |
| …and one of those was named after people | 394 |
Three things we did not do, each of which pushes the real figure one way or the other and is worth stating rather than burying.
We only asked about table names we could see or guess. Supabase no longer lets a publishable key list the tables in a project, so we read the names an app mentions in its own code and added a couple of dozen ordinary ones, capped at thirty per app. An app whose tables are named something we did not think of looks clean to us and might not be.
We counted rows, we never read them. Every probe asked the database how many rows it would hand over and stopped there. Nobody's data was downloaded, and no app is named anywhere in this article or in anything we publish.
Nearly all of the apps we could check were Lovable apps. They are the largest share of what we scanned and the most likely to name their Supabase project in the page, so read this as a measurement of Lovable apps using Supabase rather than of every builder. Where the check could not finish, we recorded that it could not finish. An app we failed to check is unknown, not clean.
An open table is not automatically a hole
From outside, a table anyone can read looks identical whether it holds your product catalogue or your customers. The response is the same. The name is the only thing that differs.
This is why we split the finding in two. In 394 of those apps, one of the
readable tables carried a name from a short list we treat as people: users,
profiles, customers, orders, messages, invoices. That is a stranger
reading your customers, and it needs fixing today.
The other 1,702 we cannot judge from outside, and neither can any other scanner.
A posts table might be a public blog, or it might be private notes. You know
which. Nobody looking at your app from the internet does.
If you would rather not guess at your own, our free scan checks your live site from outside and tells you which tables answered. It takes about 20 seconds and needs no account: scan your app.
Why this happens to apps nobody opened up on purpose
Because the fix that makes a broken app work again is usually the one that opens the table.
The sequence goes like this. Row Level Security gets switched on, either by you or by the builder. Your app immediately stops showing data, because switched on with no rules means the database refuses everybody, including you. You paste the error to your assistant, it writes a policy allowing every request, and the app works again. Nothing about it looks wrong afterwards.
That policy is the one we find. The dashboard reports the table as protected, because the switch is on and a policy exists. The article on why Row Level Security being on is not the same as being protected walks through the four states a table can be in and how to tell yours apart.
The leak you have been warned about was the rare one
Across all 30,998 apps, a Supabase secret key sitting in the browser (the key that ignores every rule you have written) turned up 3 times.
It is the leak owners hear about constantly and the one we found least often. It is serious when it happens, and worth knowing how to spot, but worry spent there is guarding a door that is almost always shut. The common opening in these apps is an ordinary table with no rule on it.
How to check your own app
Two places to look inside your Supabase database, and one way to see it from where a stranger stands.
Open the Security Advisor in your Supabase dashboard. It lists every table with Row Level Security switched off, which is the clearest version of this problem. Supabase is good at flagging it, and if your project is on that list you have your answer without reading a line of SQL.
Then read the policies on any table that holds people. The Advisor cannot decide whether a permissive policy is intentional, because for a product catalogue it would be correct. Open the table, look at the policy, and see whether it names a condition or allows everyone.
Or check it from outside, which is where the risk lives. A stranger does not open your dashboard. Our free scan makes the same anonymous request an outsider would and reports which tables answered: scan your app, no account, no install.
What to do about a table that should not be readable
What to do
- Start with the tables holding people.
users,profiles,customers,ordersandmessagesare where somebody else's data lives, and they are the ones worth an evening. - Write the rule before you widen anything else. A policy that names a condition (this row belongs to this signed-in user) is what makes the publishable key in your app safe to be there.
- Check the policy, not the toggle. Switched on with a rule that allows everybody looks the same from outside as switched off, and your dashboard shows the first one as protected.
- Leave genuinely public tables alone. A product list or a published article being readable is correct, and turning it off breaks your app for no gain.
- Test it the way a stranger would, after the change. Your app showing the right thing proves what your app requests, not what your database will hand over.
Checking this once is an evening. Keeping the answer true next month is the part that does not fit in one, and it is what we built Reeve Care to do. It re-runs this same check on your app on a schedule and emails you when the answer gets worse, because a table that was closed in March and open in June is not something anyone notices from inside their own app.
It also keeps its own backups of your Supabase database, taken on a schedule, stored outside your Supabase account and read back to verify before they count, with a restore that snapshots the current state before it replays anything. That second half matters here because we only ever check reading. The same permissive rule can allow writing, and a stranger writing to your table is the version that empties it, at which point a copy from before is the only thing that puts the rows back. Care covers your database, and the files your users uploaded once you connect them, on Supabase rather than every kind of database: what it watches and what it costs.
If you would rather work through this as a list, the 10-minute security checklist covers this alongside the other things worth closing in a newly launched app. And if a table was open for a while, what you can undo later depends entirely on what you were backing up.
FAQ
How do I find out if anyone can read my Supabase database?
Two checks answer most of it. In your Supabase dashboard, open the Security Advisor: it lists every table with Row Level Security switched off, and those are readable by anyone holding the key that ships in your app. Then open the policies on any table that holds people, because a table can pass the first check and still be open. A policy that allows everybody is switched on, valid, and reads to the dashboard as protected. If you would rather see it from outside, our free scan reads your live site the way a stranger would.
Is it bad if one of my tables is readable by anyone?
It depends on the table, and you are the only person who can decide. A list of products, published articles or venues on a map is meant to be readable by everyone, and a policy allowing that is correct. The same setting on a table of users, orders or messages means strangers can read your customers. Ask whether you would be comfortable posting that table on a public page, and let the answer decide.
I have Row Level Security turned on. Does that mean my tables are protected?
Not on its own. The switch and the rules are two separate things: switched on with no rule blocks everybody including your own app, and switched on with a permissive rule blocks nobody. The rule that gets written when an app breaks after Row Level Security goes on is usually the one that allows every request from anyone, which makes the app work and leaves the table open. Read the policy on the table, not the toggle.
My app has a login screen. Doesn't that keep people out of the database?
No. Your login screen decides what your app shows. It does not decide what your database hands over, because a request does not have to come from your app at all. The key your app carries is readable by any visitor, and it can be used against your database directly. What decides the answer is Row Level Security on each table.
What should I do first if I find a table that strangers can read?
Fix the policy on that table before anything else, then look at what was reachable while it was open. Start with the tables holding people, since those are the ones with someone else's data in them. If the table was open and holds personal data, check whether your local rules require you to tell anyone; that is a question for a lawyer rather than a scanner.