GUIDE · SECURITY

Open Firebase rules: how to lock down Firestore and Storage

The rule allow read, write: if true gives everyone access. How to spot open Firebase rules and restrict them to signed-in users or owners.

3 min readLast checked

How to spot open rules

Open rules are convenient while you build. According to the Firebase documentation you must update them before you go to production. If your rules say allow read, write: if true, anyone can read and write.

The documentation is explicit: Firebase Security Rules are the only safeguard against malicious users when the client accesses data directly.

At least: signed-in users only

The simplest tightening admits only signed-in users: allow read, write: if request.auth != null. That keeps anonymous visitors out, but not one user from seeing another user’s data.

Better: owner only

For data that belongs to one user, the rule compares the request’s user ID with the ID in the path: allow read, write: if request.auth != null && request.auth.uid == userId, with userId taken from the path. In Firestore a document path such as match /users/{userId} fits; in Storage the ID sits in the file path.

Mixed: public read, owner-only changes

Content everyone may read but only its author should change gets separate rules: read for all, plus one rule each for create, update and delete. On create you compare request.auth.uid with the author ID in the new data (request.resource.data), on update with the author ID of both the existing and the new data so nobody can change the owner, and on delete with the existing data (resource.data).

Test the rules before going live

With the Firebase Local Emulator Suite you can check Security Rules locally and automate tests before you publish them.

Common mistakes

These mistakes follow from the Firebase docs:

  • Leaving the test mode rules in place in production. In test mode, per the docs, anyone can access the data, so the rules must be changed before going live.
  • Relying on the app to do the checking. The docs put it the other way round: clients are not responsible for enforcing security, the rules are.
  • Only requiring request.auth != null although the data belongs to individual users. Every signed-in user can then see everyone else's data. Compare the user ID in that case.
  • Publishing rules without testing them first. The Emulator Suite checks them locally.

Example: lock everything first, then open up selectively

From the Firebase docs: the default rules of locked mode deny all access in Cloud Firestore. Build on that and allow only what your app needs, for example access to a user's documents under their own ID:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

Frequently asked questions

What does allow read, write: if true mean?

Anyone can read and write, even without signing in. The rule is meant for development only.

What does locked mode do?

Per the docs, its default rules deny all access in Cloud Firestore and in the Realtime Database. You then open up selectively what your app needs.

Is request.auth != null enough?

It keeps anonymous visitors out, but not users from each other. If the data belongs to individual users, compare request.auth.uid with the user ID in the path.

How do I test the rules without going live?

With the Firebase Local Emulator Suite. It checks Security Rules locally and runs tests automatically.

Sources

CHECK YOUR APP

Check your app

The free check loads your app like a visitor and shows what is visible from the outside. You confirm beforehand that you are responsible for the app or authorised to test it.

More guides

All guides →