0

I have been getting email notifications about my Firebase rules not being secure even though I set the data to be readable only by authenticated users and I set the write to be false. My application basically shows currency exchange rates and I create an anonymous user once the app loads for the user to be able to read the data so I think it makes sense to have such rules? Here are my rules:

{
  "rules": {
    ".read": "auth.uid != null",
    ".write": false
  }
}

Update: I updated my rules to:

{
  "rules": {
    "currencies":{
       ".read": "auth.uid != null",
    },
    ".write": false
  }
}

And here is my data: (https://i.stack.imgur.com/in1BV.png)

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807

1 Answers1

2

I set the data to be readable only by authenticated users

While that is a good starting point, it means I can get all your (user's) data by signing in and reading the root. This is not secure and open to abuse, which is why you receive alerts about it.

You should follow the principle of least privilege, and only allow in your rules exactly what your code does.


In the unlikely event that your code really reads the root, you can disable the alert in the Firebase console.


In all other cases, you'll want to reduce the read permission to exactly how your code reads it. For example, if your code reads from two top-level nodes, you can secure that with:

{
  "rules": {
    "users": {
      ".read": "auth.uid != null",
    },
    "messages": {
      ".read": "auth.uid != null",
    },
    ".write": false
  }
}

In a scenario like this, you're likely to read the /messages first, and then read the profile information for specific users mentioned in those messages. You can better secure that like this:

{
  "rules": {
    "users": {
      "$uid": { 
        ".read": "auth.uid != null",
      }
    },
    "messages": {
      ".read": "auth.uid != null",
    },
    ".write": false
  }
}

Now a malicious user can't read all of /users in one go, but can read the profile only once they know the UID. A sufficiently motivated user can still read your entire database, but it'll take a lot more effort - which discourages abuse.


Also think of whether the user needs to read all message, or (say) maybe just the 50 most recent ones. The latter use-case you can secure better with query based security rules:

"messages": {
  ".read": "auth.uid != null &&
            query.orderByChild == 'timestamp' && &&
            query.limitToLast <= 50"
},

Now the user can only read the 50 most recent messages, and thus (with the previous) also only the user profiles that participated in those messages.


Finishing off with the golden rule: only allow in your rules exactly what your code does. Make sure your code works, but any different API calls get rejected.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Still got the email ‍♀️ my real-time database has a "currencies" node under the root so I put "currencies":{".read": "auth.uid != null", }, ". write": false – Yousef Baghlaf Oct 10 '21 at 17:23
  • The rules that I build in my answer are guaranteed to stop the alerts. If you think you've done enough to stop them too, edit your question to show your complete new rules and I'll have another look. – Frank van Puffelen Oct 10 '21 at 18:13
  • I updated the question with the new rules – Yousef Baghlaf Oct 10 '21 at 20:06
  • The updated rules in your question should no longer be triggering the alert from Firebase. Note that it may take 24 hours before the alerts stop coming. If they still come after that time, [reach out to Firebase support](https://firebase.google.com/support/contact/troubleshooting/) for personalized help in troubleshooting – Frank van Puffelen Oct 10 '21 at 20:11