Späť na blog
14. augusta 2026

Firebase Security Rules Left Wide Open: allow read, write: if true

Viktor Bulanek
Founder & CTO, Penetrify
MSc IT Security · 20+ years in security · 4x Ex-CTO

Firestore and Realtime Database are not protected by your application. They are protected by rules that live in the database and are evaluated on every request, because the client talks to the database directly. Get the rules wrong and there is no server-side code to save you — the security boundary is the rule file, and nothing else.

The most common way to get it wrong is not subtle. It is allow read, write: if true;, left in place from the day the project was created.

How the Default Becomes Production

When you create a Firestore database, the console offers test mode and production mode. Test mode writes a rule that allows all reads and writes for thirty days, and it exists for a good reason: it lets you build without fighting permissions while nothing real is in the database.

Then the thirty days lapse, the app breaks, and the fastest fix — the one every tutorial and Stack Overflow answer suggests — is to change the timestamp condition to if true. Development continues. The app ships. The rule is still there, and now it guards real customer data.

The pattern concentrates in a specific kind of project: mobile and web MVPs built quickly, often with Flutter or React Native, frequently by teams whose strength is product rather than backend. Firebase is popular precisely because it removes the backend, and removing the backend also removes the place where authorisation normally lives. That trade is fine as long as the rules take up the job, and the rules are the first thing to be postponed.

What "Wide Open" Actually Exposes

Your Firebase project ID is not a secret — it is in your client bundle and in your mobile app, because the client needs it to connect. With the ID and an open rule, anyone can query the database over the public REST and SDK endpoints without touching your application at all.

Read access means the entire collection tree: user documents, order history, chat messages, uploaded file references, any admin collection you created for internal tooling. Write access means creating and modifying documents — changing a subscription field, editing a price, inserting content that your app will render to other users, or deleting collections outright.

Two consequences catch teams by surprise. First, your application's own validation is irrelevant, because requests never pass through it: a field your UI would never send is accepted if the rule permits the write. Second, your billing is exposed — Firestore charges per document read, so an open database is not only a data breach but a cost incident, and a script iterating your collections can run a bill up fast.

Storage rules deserve the same look. The same permissive pattern in storage.rules makes every uploaded file readable, and lets an attacker replace a file with one of their own choosing.

The Failure Modes That Look Secure and Are Not

Beyond if true, three rule patterns pass a glance and fail a test.

Authenticated is not authorised. allow read, write: if request.auth != null; is the second most common rule we see, and it means any signed-in user can read and write everything — including other users' documents. If your app allows self-service signup, this is functionally open to the internet with one extra step.

Ownership checked on read, not on write. Rules are often written carefully for read and loosely for write, because reads are what the developer was debugging. The result is a database where you cannot see someone else's document but you can overwrite it.

Validation missing on shape. Even a correct ownership rule permits a user to write arbitrary fields into their own document — including role: "admin" or plan: "enterprise", if your application trusts those fields. Rules can constrain the shape of a write with request.resource.data, and most rule files never do.

How to Check Your Own Project

Read the rules first, in the Firebase console under Firestore or Realtime Database, and again under Storage. If you see if true, or a bare request.auth != null on a collection holding user data, you have your answer without testing anything.

Then test empirically, because the rules you deployed are not always the rules you have in your repository. Create two ordinary user accounts, and from account A attempt to read and write a document belonging to account B:

# Firestore REST, as an authenticated user
curl -H "Authorization: Bearer <id-token-for-user-A>" \
  "https://firestore.googleapis.com/v1/projects/<project-id>/databases/(default)/documents/users/<user-B-doc-id>"

Any response other than a permission error is a finding. Repeat without a token at all, which tests the unauthenticated path, and repeat for writes rather than assuming they mirror reads. The Firebase emulator suite runs the same rules locally, so these checks belong in your test suite rather than in a periodic audit.

The Fix

Write rules that assert ownership and shape, per collection, and deny by default. The general form is unglamorous and effective:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read: if request.auth != null && request.auth.uid == userId;
      allow update: if request.auth != null && request.auth.uid == userId
        && !request.resource.data.diff(resource.data).affectedKeys()
             .hasAny(['role', 'plan', 'credits']);
    }
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Three things are doing the work there: ownership is checked against the authenticated UID rather than against a field in the document, privileged fields are explicitly excluded from what a user may change, and the catch-all at the end denies anything you forgot to write a rule for. That last clause is the one that converts an incomplete rule file from dangerous to merely incomplete.

Then move rules into CI. They are a text file in your repository, the emulator can evaluate them, and a test that asserts "user A cannot read user B's document" is a few lines. Rules that are only reviewed when something breaks will drift, because every new collection is a new opportunity to forget.

Why This Keeps Happening

Because the platform's greatest strength is also where it puts the sharpest edge. Firebase lets a small team ship a real product without a backend, and in exchange it asks them to implement authorisation in a declarative language they will use once and then not touch for a year. The permissive rule is not laziness; it is the only state in which the tutorial works.

It also fails silently in the direction of working. An over-permissive rule never produces an error, never breaks a build, and never appears in a bug report — the app functions perfectly, for everyone, including people who are not your users. That combination is why this class survives code review and lands in automated testing instead: a scan can hold two accounts and try the thing your rules were supposed to prevent, which is the only way to know they do.

Frequently Asked Questions

Aké typy zraniteľností Penetrify detekuje?

Penetrify detekuje všetky kategórie zraniteľností OWASP Top 10 vrátane SQL injection, XSS, CSRF, IDOR, nefunkčnej autentifikácie, bezpečnostných miskonfigurácií a úniku citlivých dát. Testuje tiež bezpečnosť API, správu relácií a bežné miskonfigurácie v Supabase, Firebase a Bubble.

Ako dlho trvá AI penetračný test?

Rýchle skenovanie je dokončené za 15–30 minút. Štandardné skenovanie trvá 1–2 hodiny s širším pokrytím. Hĺbkové skenovanie môže trvať niekoľko hodín pre zložité aplikácie.

Čo obsahuje správa Penetrify?

Každá správa obsahuje executive summary, celkové bezpečnostné skóre, nálezy klasifikované podľa závažnosti (Kritické, Vysoké, Stredné, Nízke), podrobné kroky pre reprodukciu a konkrétne odporúčania pre nápravu napísané pre vývojárov – nie pre špecialistov na súlad.

Related articles

Zastavte úzke miesta DevSecOps pomocou automatizovaného bezpečnostného testovania
Zastavte DevSecOps prekážky, ktoré spomaľujú váš pipeline. Zistite, ako automatizované bezpečnostné testovanie umožňuje skutočný "shift left" bez straty rýchlosti. Čítajte viac teraz!
Tajný kľúč Stripe vo frontendovom balíku: 4 mesiace tichej expozície
Dvojčlenný tím vybudoval marketplace na platforme Bubble.io, ktorý spracúval platby v hodnote viac ako 40 000 USD. Ich tajný API kľúč služby Stripe sa štyri mesiace nachádzal v JavaScriptovom balíku na strane klienta – čo komukoľvek, kto sa pozrel, poskytovalo plný prístup na čítanie a zápis k celej ich platobnej infraštruktúre. Tu je, ako sa to stalo, čo bolo v ohrození a čo s tým urobili.
Skenovanie pre súlad s PCI DSS: Sprievodca automatizovaným zabezpečením pre rok 2026
Dňa 14. marca 2025 maloobchodný predajca prvej kategórie zistil, že jediné nesprávne nakonfigurované pravidlo firewallu počas piatkového popoludňajšieho nasadenia znehodnotilo tri mesiace príprav na dodržiavanie súladu v priebehu menej ako šiestich minút. Pravdepodobne už viete, že tradičné štvrťročné skenovanie pre PCI DSS compliance pripomína kontrolu tachometra…

Explore more