Retour au blog
14 août 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

Quels types de vulnérabilités Penetrify détecte-t-il ?

Penetrify détecte toutes les catégories de vulnérabilités OWASP Top 10, notamment les injections SQL, XSS, CSRF, IDOR, les failles d'authentification, les mauvaises configurations de sécurité et l'exposition de données sensibles. Il teste également la sécurité des API, la gestion des sessions et les mauvaises configurations courantes dans Supabase, Firebase et Bubble.

Combien de temps dure un test de pénétration IA ?

Un scan rapide se termine en 15–30 minutes. Un scan standard dure 1–2 heures avec une couverture plus large. Un scan approfondi peut durer plusieurs heures pour les applications complexes.

Que contient un rapport Penetrify ?

Chaque rapport comprend un résumé exécutif, un score de sécurité global, des résultats classés par gravité (Critique, Élevé, Moyen, Faible), des étapes de reproduction détaillées et des recommandations de remédiation concrètes rédigées pour les développeurs – pas pour les responsables conformité.

Related articles

Mettre fin aux goulots d'étranglement DevSecOps grâce aux tests de sécurité automatisés
Éliminez les goulots d'étranglement DevSecOps qui ralentissent votre pipeline. Découvrez comment les tests de sécurité automatisés permettent un véritable "shift left" sans sacrifier la vitesse. En savoir plus dès maintenant !
La clé secrète Stripe dans le bundle frontend : 4 mois d'exposition silencieuse
Une équipe de deux personnes a créé une place de marché Bubble.io traitant plus de 40 000 $ de paiements. Leur clé secrète d'API Stripe était restée dans le bundle JavaScript côté client pendant quatre mois — donnant à quiconque l'aurait consultée un accès complet en lecture/écriture à toute leur infrastructure de paiement. Voici comment cela s'est produit, ce qui était en jeu et ce qu'ils ont fait pour y remédier.
Analyse de conformité PCI DSS : Le guide 2026 de la sécurité automatisée
Le 14 mars 2025, un important détaillant a découvert qu'une simple règle de pare-feu mal configurée lors d'une mise en production un vendredi après-midi avait anéanti trois mois de préparation à la conformité en moins de six minutes. Vous savez probablement déjà que les analyses trimestrielles traditionnelles de conformité PCI DSS donnent l'impression de vérifier son compteur de vitesse…

Explore more