Common Mistakes in Firebase Security Rules (Part 1)

If you have ever developed a mobile app or a website using Firebase Realtime Database, you must have written security rules.

Since your client side application communicates directly with your Firebase Realtime Database, the only thing separating an attacker from compromising your database is your security rules.
Therefore, the task of writing security rules should be taken very seriously.

In this article I’m going to describe a common mistake developers do while writing security rules: ignoring the fact that rules cascade.

In order to estimate how common this mistake is, I sampled 950 open source GitHub projects with non trivial rules.
228 of them (almost 25%) were found vulnerable due to it.
Some examples can be found here:
https://github.com/TarikHuber/react-most-wanted/pull/28
https://github.com/calvingerling/booktionator/pull/63
https://github.com/Methodician/ScatterSchool/issues/56


Rules Cascade

Read and Write rules cascade. It means that granting read/write access to a node grants read/write access to all of its child nodes.

In order to demonstrate what can go wrong I will outline two examples, based on real projects.

Consider the following trivial rules:

Anyone can read and write /. Let’s say that we want to add a node to the database for user sessions and grant read and write permissions for a session, only to the user who owns that session (e.g only a user with uid bob can read and write /sessions/bob).

Take a look at the following rules:

Now, only bob can read and write /sessions/bob and nobody can read and write /sessions, right?

Unfortunately, the opposite is true. Anyone can read and write /sessions/bob. Actually anyone can read and write /, and there is no difference between these rules and the first ones.
They are completely equivalent, because read and write rules cascade.

The correct way to obtain the desired functionality is:

Note that I omitted the "read": false and the "write": false under session since the default access is false.

Our second example is:

correct_rules_2.json

Any authenticated client can read and write /users, but due to the rules under /users/$uid we can infer that allowing such access was not intentional.

Similar to the first example, the fix should be:

What should you do?

You should take your time writing security rules as it is critical to your application security. Cascading rules bugs occurs because of lack of understanding in Firebase rules or poor maintenance.

Changes to your security rules should be tested and monitored as a part of your development life cycle.

In order to do so, we recommend using the Bolt compiler to simplify the process of writing rules and Targaryen to test your rules according to specific scenarios in your application.

Finally, we at Noless created a basic service that scans a JSON rules file and detects cascading rule bugs. You can try it out here.