Skip to content
Back to Blog

Is my Firebase database open to the public? How to check

Eliott Reich, founder of TaskBounty3 min read
security
firebase
vibe coding
ai dev tools

Firebase is a fast way to give an app a backend without running one yourself. It is also a common place for AI-built apps to leak data, and almost always for the same reason: the security rules were opened up during development and never closed again. If that describes your project, here is how to check whether your database is open to the public, and how to fix it.

Why this happens

Firebase Realtime Database and Firestore both start locked. New projects deny reads and writes by default, which is the right posture. The trouble starts when something does not work during development, a quick search suggests loosening the rules, and you end up with something like this in your Realtime Database:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Or the Firestore equivalent, an allow read, write: if true. Everything works in the demo, so the wide-open rule never gets tightened. The app ships, and now anyone who knows your database URL can read, and often write, your data. Your Firebase config, including that URL and the public API key, ships in your app's JavaScript, so it is not a secret.

It is not a bug in Firebase. It is a development shortcut that quietly becomes a production hole, and there is no error to warn you.

The manual check

  1. Open the Firebase console, go to your database, and look at the Rules tab. Read them carefully. A .read: true or allow read: if true means public read access.
  2. Prove it from the outside. Your Realtime Database responds to a plain HTTPS request. Appending .json to your database URL, for example https://your-project.firebaseio.com/.json, will return data if the rules are open. If you get your records back without any authentication, the database is public.
  3. For Firestore, check whether your collections are readable through the REST API with only the public config. If unauthenticated reads return documents, your rules are too loose.

If any of these return real data to an anonymous request, treat everything in that database as public until you fix the rules.

The fix

The goal is the same as with any backend: reads and writes should require the right authenticated user, not merely a valid request. A safer Realtime Database rule scopes data to its owner:

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

For Firestore, the same idea in its rules language:

match /users/{userId} {
  allow read, write: if request.auth != null && request.auth.uid == userId;
}

The pattern is to require an authenticated user and to check that the user owns the data they are touching. Avoid any rule that grants access on true alone to a collection that holds anything private. As with Supabase, test as an anonymous user and as a second signed-in user to confirm the boundaries hold.

Check it in a few seconds

Reading rules by hand is a good habit, but it is easy to miss a path or a collection. Our Firebase open database check makes an unauthenticated read against your public database from the outside and tells you whether it responds with data. It is read-only and never writes, so it is safe to run against a live app.

If it finds an open database and you would rather have it closed and verified for you, we can tighten the rules and prove the fix in a reviewable pull request, with a full refund if we miss a confirmed issue. Either way, the important move is to know for certain, rather than assume the defaults held.

Related