i'm trying to understand how security rules structure is working. I have these rules:
{
"rules": {
"level1": { //public info
".read": true,
".write": true,
"level2": { //private info
".read": false,
".write": false
}
}
}
}
then testing with simulator i expected to have r/w access to level1, and NOT to level2...
but result was i have r/w access to both levels.
How is that? Am i missing something?
Thanks.
When you grant (read or write) access on one level, you can not revoke access on a lower level. See this quote from the Firebase documentation on security:
Rules Cascade
SECURITY AND FIREBASE RULES WORK FROM THE TOP-DOWN
This is a critical concept of understanding Security and Firebase Rules. The child rules can only grant additional privileges to what parent nodes have already declared. They cannot revoke a read or write privilege.
Related
I have the following Firebase realtime database rules:
{
"rules": {
".read" : "auth != null",
".write": false,
"Games": {
".indexOn" : "WeekId"
},
"Version": {
".read" : true
}
...
}
I keep getting the following email from Google:
[Firebase] Your Realtime Database 'xxx-9e542' has insecure rules`
We've detected the following issue(s) with your security rules:
any logged-in user can read your entire database
Without strong security rules, anyone who has the address of your database can read / write to it, leaving your data vulnerable to attackers stealing, modifying, or deleting data as well as creating costly operations.
So based on my rules above, I KNOW, that I have rules in place to allow logged in users to read the Games node and that ALL users can read the Version node even non authenticated users.
As far as I know, it needs to be this way because I require ALL logged in users to be able to access the Games node information, else how would they be able to view the list of games they can select from!?
As for the Version node, I use that in the instance I need everyone that downloaded my app to "Force Upgrade" my app cause of a change that is required. In this instance, I would need the user that have downloaded an older version of my app and that are either "logged in" or "not logged in" and force them to update the app or else they can not use it.
Can anyone let me know if I am off base with how I structured my security rules or is this "normal" and that I am receiving the email just as a FYI!?
How have others setup their rules!? or what are the "best practices" for setting up security rules!? esp. if you need logged in users to access the information of any particular node(s) 24/7!?
The main problem with your current rules is that anyone can sign in through the API and read your entire database, even if they know nothing about your application. They can just read the root of the database, and then start looking at your data.
The first step to improve security would be to not allow read on the top-level, but only at lower levels:
{
"rules": {
".write": false,
"Games": {
".read" : "auth != null",
".indexOn" : "WeekId"
},
"Version": {
".read" : true
}
...
}
Now nobody can read from the root, and you must know that Games or Version node exists in order to read it.
I am using Relatime database from firebase to read few flags and do some actions in android app. I used to get mail of insecure database read and write rules so I changed to following:
{
"rules": {
".read": "true",
".write": "false"
}
}
And now, I only get mail about insecure read.
[Firebase] Your Realtime Database 'abc-xyz' has insecure rules
We've detected the following issue(s) with your security rules:
any user can read your entire database
But if I change read to false then I am unable to read any value changes in real time. Can someone please help me understand how do I secure both read and write but also able to keep reading values from app?
PS: I don't use Firebase auth in my app as of now.
Firebase Auth is a cool thing, if you don't want your user to log into the authorization provider account, you can use an anonymous account which gives you a unique user ID of your app, etc.
Then you can write rules like:
"rules": {
".read": "auth != null",
".write": "auth != null"
}
If you don't store user data, you probably don't need any authorization. You can still restrict reading and writing of users by adding some area when read / write is available.
E.g:
"rules": {
"PublicData":{
"SomePublicChild":{
"ChildProperty1": { ".validate":true },
"ChildProperty2": { ".validate":true },
"$other": {".validate":false },
},
".write":true,
".read":true,
".validate":"newData.hasChild(SomePublicChild)"
},
"PrivateData":{
".write":false,
".read":false,
}}
These rules will allow anyone to write / read to the PublicData node and to anyone else to write / read the PrivateData node. The rules will also protect the structure of your public data, they only allow writing to the PublicData object with the ChildProperty1 or ChildProperty2 properties, and will block writes with any other property key.
It's not big thing but you won't recive more mail about insecure rules.
I have a firebase real-time database connected to my angular 6 project,
the write rule in my database is set to false since I'me using functions to add, edit, delete anything in the database
and the rules in the rule's tab is like this
"rules": {
".read": "auth != null",
".write": false,
}
}
So my question is how can I disable the read, only for one node lets name it 'companies', cause I need to give it more security and send read request also using functions for that node only.
P.S: I have a lot of nodes beside of 'companies node'
Once a node has been given read access, that can't be revoked by a later rule. From the documentation:
{
"rules": {
"foo": {
".read": true,
".write": false
}
}
}
.read and .write rules cascade, so this ruleset grants read access to
any data at path /foo/ as well as any deeper paths such as
/foo/bar/baz. Note that .read and .write rules shallower in the
database override deeper rules, so read access to /foo/bar/baz would
still be granted in this example even if a rule at the path
/foo/bar/baz evaluated to false.
So, a shallow grant to read access at the root of your database can't be changed later in a deeper node.
You will have to expand your rules to allow access to only the nodes that you want the user to read, and omit the children you want to reject access to.
I'm developing a proof-of-concept application, and thus my security requirements are low. I therefore changed the access rules to public access:
{
"rules": {
".read": true,
".write": true
}
}
This works as expected. The problem is that after a few minutes, the rules change back to default values (auth required) and I get an access error "Error: permission_denied at /cases: Client doesn't have permission to access the desired data."
Why on earth is this so?
Thanks.
You must edit database.rules.json in your IDE then save it then deploy it.
Is there any way to temporarily disable all access to your Firebase database, sort of like a kill switch? I know you can alter the rules so that everything if false, which will restrict anything which doesn't have administrator access, but is there a more elegant solution?
To prevent anyone from accessing your database, just set these rules in the rules tab of your database:
{
"rules": {
".read": false,
".write": false
}
}