Home > Enterprise >  Realtime Database from insecure to secure rules without interrupting services
Realtime Database from insecure to secure rules without interrupting services

Time:11-16

Today, I received an email which states,

[Firebase] Your Realtime Database 'CC-default-rtdb' has insecure rules, any user can read your entire database, any user can write to your entire database

My server runs every day to store values in the Realtime Database. When I started this Firebase project, I used the basic read and write rules.

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

If I change the rules now, does it affect my external Node.JS server from storing values into the Realtime DB?

I even access this DB from a mobile app, so will it affect the mobile app from reading data if the rules are changed?

How can I secure these Realtime DB rules (from public to private) without interrupting the access for the external server and mobile app? Importantly, my external server access must not get disrupted.

CodePudding user response:

If you are accessing your database through authentication(login) you can set your nodes to auth!=null so that any unauthorized user cannot access them.

You need to follow the following steps:

  1. Set read to true for all nodes you need to make publicly available
  2. Set read/write to auth!=null for all nodes you want to make available to any authorized user
  3. Set custom validation rules for any node that needs special access (e.g.: A user can only write to his/her data)

As per the screenshot, if anyone gets a hold of your project id, they can modify and steal your entire database.

You need to set rules in a way that properly matches your use case. As far as I understand:

  • Allow the external server account access to the whole DB
  • Allow the mobile app conditional access (by user perhaps?)

Example

Take this database for instance:

{
  "top_level": {
    "users": [
      {
        "username": "X",
        "userId": "0"
      },
      {
        "username": "Y",
        "userId": "1"
      }
    ],
    "public_data": {
      "news": [
        {
          "title": "X",
          "body": "Y"
        }
      ]
    }
  }
}

I want to set:

  • Node "news" to be publicly available to read (no auth)
  • Node "users" to be only available to other logged-in users to read(auth)
  • Children of node "users" to only be writable for the user whose id matches the value userId in the node

The rule, in this case, would be:

{
  "rules": {
    ".read": false,
    ".write": false,
    "top_level": {
      "users": {
        ".read": "auth!=null", 
        "$user_id": {
          ".write": "auth!=null && data.child('userId').val()===auth.uid"
        }
      },
        "news" : {
          ".read":true
        }
    }
  }
}

Note, rules set as true in the top-level override inner rules. Comment if you need clarification.

  • Related