Fix guide · critical · firebase_rtdb_open

Firebase Realtime Database root readable without authentication

What this rule means

A GET to https://<project>.firebaseio.com/.json returned data without an auth token. Your RTDB security rules grant .read: true at the root — every node in the database is enumerable by anyone with the project ID (which is in your client bundle).

Why it matters

RTDB's default rules in test mode grant ".read": true, ".write": true at the root. The Firebase Console explicitly warns this is for development only and locks them after 30 days — but apps regularly ship before the lockdown fires, or devs extend the timer to keep dev moving. Once a single attacker pulls /.json, they have the entire database. The shape isn't theoretical; the same misconfiguration produced the FireStorage exposure scans in 2023 and surfaces in every fingerprinting tool today.

How to fix it

Replace the rules with explicit, path-scoped policies. Console → Realtime Database → Rules:

{
  "rules": {
    ".read": false,
    ".write": false,
    "users": {
      "$uid": {
        ".read": "auth != null && auth.uid == $uid",
        ".write": "auth != null && auth.uid == $uid"
      }
    },
    "posts": {
      ".read": "auth != null",
      "$postId": {
        ".write": "auth != null && (!data.exists() || data.child('authorId').val() == auth.uid)"
      }
    }
  }
}

Key principles:

  1. Default-deny at the root. ".read": false, ".write": false at the top stops the whole-tree dump.
  2. Grant access at the leaf. Each path explicitly says who can read or write what.
  3. Use $uid and $postId variables to enforce ownership instead of trusting client-supplied IDs.
  4. Validate writes. Add .validate rules with type and shape checks; otherwise authenticated users can still write garbage.

After publishing rules, run the Rules Playground (Console → Rules → Simulator) with auth=null to confirm nothing returns. Then with a test UID to confirm only that user's nodes are reachable.

Full guide: /blog/firebase-rules-vibe-coded.

Did vibecheck flag this on your app?

If you reached this page from a vibecheck inspection report, the redacted match in your scan output is the exact string we found in your bundle. After applying the fix above, run the inspection again — the finding should clear.

Run another inspection