Skip to content

Is your Supabase or Firebase database public? A five-minute check for vibe-coded apps

Supabase and Firebase both ship with a public key that's meant to be seen. What decides whether it can read your data is Row Level Security or Security Rules, the one setting AI-generated app setups usually skip. A five-minute way to check your own database.

· Rampa

You asked Claude, Cursor, or v0 to add a database to your app, it wired up Supabase or Firebase in a few minutes, you tested it, it worked, and you shipped. What most AI coding tools do not set up by default is the one setting that decides who can read every row in that database once your app is live on the internet.

This is the same review Rampa Solutions runs before you ship anything built with AI: accessible, secure, private, legal, and no surprise bills. This piece is about the security light specifically, and about a gap that is easy to miss because the app works perfectly either way: a database that anyone on the internet can read, and sometimes write to, without ever logging in.

What actually makes a database public

Supabase and Firebase both ship with a key that is meant to sit in your browser's JavaScript, visible to anyone who looks: Supabase calls it the anon key, Firebase calls it the client config. That part is normal and by design; the key itself is not the secret.

What decides whether that key can read your data is a separate setting: Row Level Security (RLS, the rules that say which rows a request is allowed to touch) in Supabase, or Security Rules in Firebase. When a table has no RLS policy, or a database is left at its starting default rules, the public key can read, and sometimes write, every row, because nothing tells it not to.

Most starter templates and AI-generated setups get you a working table before they get you a working rule. The database works fine in your first test, because you are testing it as yourself, signed in, with no rule getting in the way.

How common this actually is

In 2020, security researchers at Comparitech scanned more than half a million Android apps and found over 150,000 using Firebase. Close to 12,000 of those had a publicly exposed database, and about three out of four of those also allowed public writes, not just reads. Those were finished, published apps, not weekend projects.

A vibe-coded app skips even more of the setup that used to happen by default, since there is usually no backend engineer double-checking the database before launch. The database is not broken. It was simply never told who is allowed to read it.

What is actually at risk

If a table has no RLS or rules and holds anything more than public content, whatever is in it is readable by anyone who opens your browser's developer tools and copies the project URL and the public key, both of which are already sitting in the JavaScript your site loads.

  • User emails, names, or phone numbers from a signup or waitlist form.
  • Private messages, orders, or any row tied to one user that should not be visible to another.
  • Anything left with write access open: someone can add, edit, or delete data, not just read it.

None of this needs a sophisticated attacker. Scanners that look for exposed Supabase and Firebase projects across the public internet run constantly, and a brand-new app is found the same way an old one is.

How to check your own database in five minutes

Open your live site and your browser's developer tools (F12 on most browsers), go to the Network tab, and reload the page. Look for a request to a URL that includes supabase.co, or firebaseio.com / firestore.googleapis.com: that request carries your project's public key.

For Supabase: open your project dashboard, sign out or use a private browser window with no session, then try reading a table from the browser console using your project URL and anon key. If rows come back with nobody signed in, RLS is off, or the table has no policy attached.

For Firebase: in the Firebase console, open Firestore Database (or Realtime Database) and go to the Rules tab. If you see something like `allow read, write: if true;`, or the rules were never edited past the starting template, the database is open to anyone who asks.

The Supabase dashboard also shows a warning on any table with RLS turned off. If you have never seen that warning, it is worth checking directly rather than assuming no warning means no problem.

How to fix it without rewriting the app

  • In Supabase, turn on RLS on every table, then add a policy. Even a simple one, such as "a user can only read rows where user_id matches their own id," closes the gap for private data. A table meant to be public, like a blog post table, can keep a policy that allows anyone to read it.
  • In Firebase, replace the default or wide-open rule with one scoped to the signed-in user, using `request.auth.uid` to match rows to the person making the request.
  • If a table was open and held real user data, treat it as already seen. Rotating a public key does not undo a copy someone already made before the fix. Check your project's usage logs for unusual read volume from before today.
  • Do this table by table. One unprotected table undoes the work on every other table that is already set up correctly.

This is different from most of what a passive security check can look at on its own: testing whether a database is actually open means using your own key against your own project, so it only runs on sites verified as yours, with your written OK first. Everything above this line, you can check yourself, right now, in about five minutes.

Get a free, passive check of what your site already shows in public, no account needed: https://rampa.solutions/?de=blog-is-your-supabase-firebase-database-public

Sources

Find out where your site stands, now

Enter your address. In about a minute: every failure on the page explained without jargon, and the corrected code for what we can fix. Free, no account.

Free scan, right here · no account

Keep reading

Automated testing covers roughly half of WCAG criteria; a full conformance claim also requires manual review. Technical information, not legal advice.