Create firebase rules for dynamic and static nodes with exception fields - firebase

I have static nodes like (users-technical-services-orders),
for example (technical) I created (write restrict) to only same technical, except 3 fields be allowed to write for all users which have authenticated.
I can do it like this:
{
"rules": {
//
"phonenumbers":{
".read": true,
".write": "auth !== null"
},
"services":{
".read": true,
".write": "auth !== null"
},
"subservices":{
".read": true,
".write": "auth !== null"
},
"ChargeRecordsProv":{
".read": "auth !== null",
".write": "auth !== null"
},
"ChargeRecordsUsers":{
".read": "auth !== null",
".write": "auth !== null"
},
"ExchangeRecords":{
".read": "auth !== null",
".write": "auth !== null"
},
"directions":{
".read": "auth !== null",
".write": "auth !== null"
},
"orders":{
".read": "auth !== null",
".write": "auth !== null"
},
"setting":{
".read": "auth !== null",
},
"technical":{
".read": "auth !== null",
"$user_id": {
".write": "$user_id === auth.uid"
},
"balancepro": {
".write": "auth !== null"
},
"ratingNumClinets": {
".write": "auth !== null"
},
"ratingDegree": {
".write": "auth !== null"
},
"statusProv": {
".write": true
}
},
"users":{
".read": "auth !== null",
"$user_id": {
".write": "$user_id === auth.uid"
}
}
}
}
This is work good for my static nodes.
the problem is:
I have a dynamic nodes like (Technicians_Carpenter_location) which his name can not be known, because it depended on what the admin can set.
these dynamic nodes will be not allowed to read or write with my previous rules.
if I add a public rules like this:
".read": "auth !== null",
".write": "auth !== null"
It can be read and write but this will effect on all previous rules for static nodes and will not be work.
So, please make a suggestion, what I can do?

I think you're looking for a wildcard rule, which matches all child nodes that are not matched by any other rule. A simple example of such a rule is:
{
"rules": {
"profiles": {
"$profileid": {
".read": true
}
}
}
}
With the above rule, anyone can read a specific profile (for example /profiles/puf), but nobody can read all profiles at once (/profiles).
So in your case, if you want to grant specific permissions to specific named nodes, and a common set of permissions to all other nodes, you'd add a wildcard to your current nodes. Something like this:
{
"rules": {
"phonenumbers":{
".read": true,
".write": "auth !== null"
},
...
"$other": {
".read": "auth !== null",
".write": "auth !== null"
}
}
}

Related

Firebase Realtime Database Insecure Rule Warning

I keep getting emails saying my database is not secure after implementing my security rules. The emails specify that any authenticated user can read/write to my database but I implemented specific access rules:
{
"rules": {
"posts": {
".read": "auth.uid !== null",
".write": "auth.uid !== null && newData.hasChildren(['score', 'quote',
'description', 'source', 'sourceType', 'ownerID', 'ownerImageURl', 'ownerUsername', 'timestamp', 'usersVoted'])",
".indexOn":["sourceType", "ownerID"],
"$postID": {
".write": "!data.hasChild('ownerID')",
"score": {
".write": "newData.isNumber() && (newData.val() === data.val() + 1 || newData.val() === data.val() - 1) && !root.child('posts').child('$postID').child('usersVoted').hasChild(auth.uid)"
},
"usersVoted": {
".write": "!data.hasChild(auth.uid)",
"$userID": {
".write": false
}
}
}
},
"users": {
".write":"auth.uid !== null && !data.hasChild(auth.uid)",
"$userID": {
".read": "auth.uid === $userID",
".write": "auth.uid === $userID"
}
},
"comments": {
".read": "auth.uid !== null",
"$postID": {
".write": "auth.uid !== null",
"$commentID": {
".write": false
}
}
}
}
}
Why does Firebase think that any user can read/write to any location in my database?
EDIT: I haven't gotten the email in a while so I think my rules are secure.
For example this rule for users node, is not secure:
"users": {
".write":"auth.uid !== null && !data.hasChild(auth.uid)",
"$userID": {
".read": "auth.uid === $userID",
".write": "auth.uid === $userID"
}
}
Because, this rule allows any authenticated user and non-existing user to write to your users node (not secure):
".write":"auth.uid !== null && !data.hasChild(auth.uid)",
and it overwrites this rule (as if this is meaningless now):
".write": "auth.uid === $userID"
To make it secure, users rule must look like this:
"users": {
"$userID": {
".write":"auth.uid !== null && !data.hasChild(auth.uid) && auth.uid === $userID",
".read": "auth.uid === $userID"
}
}
So fix your rules, and be careful of RULES CASCADING.

In the app permission is also denied in the firebase emulator

I am new to coding
The database contains the following cats
url
https://"bucket_name".firebaseio.com/Users/ID/"$uid"
{
"Age" : "\"2000,0,0\"",
"Points today" : "110",
"Questions" : {
"All questions" : {
},
"Default questions" : {
}
},
"Ready to challenge" : "\"yes\"",
"Spirit" : "5",
"account status" : "\"active\"",
"country" : "\"AE\"",
"email" : "\"email\"",
"language" : "\"ar\"",
"name" : "\"name\"",
"password " : "\"siwasiwa\"",
"phone number" : "\"\"",
"points" : "120",
"profile picture" : "\"55\"",
"timezone" : "\"123"",
"user name" : "\"\""
I activated google authentication in the project as follows firebase rules look
{
"rules": {
"bucket_name":{
"Users":{
"ID" :{
"$uid": {
"Age": {
".read": true,
".write": "auth.uid == $uid"
},
"Points today": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"Questions": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"Spirit": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"Ready to challenge": {
".read": "auth != null",
".write": "auth != null"
},
"account status": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"country": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"email": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"language": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"name": {
".read": true,
".write": "auth.uid == $uid"
},
"password": {
".read": "auth.uid == $uid",
".write": "auth.uid == $uid"
},
"phone number": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"points": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"profile picture": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"timezone": {
".read": "auth != null",
".write": "auth.uid == $uid"
},
"user name": {
".read": "auth != null",
".write": "auth.uid == $uid"
}
}
}
},
}
}
}
The result every time I do the simulation read and write is rejected
Also, he tried more than one way, but to no avail
It looks like you're trying to use Realtime database security rules to protect a storage bucket. That's not possible. Cloud Storage has a completely different set of rules to use. These are described in the documentation.

Firebase Rules: We've detected the following issue(s) with your security rules

appreciate this looks like this is been answered various times for individual requirements. Completely new to Firebase and I want to get some insight into this. I have been presented with the message from Firebase.
We've detected the following issue(s) with your security rules:
any logged-in user can read your entire database
any logged-in user can write to your entire database
My current rules look like this:
{
"rules": {
".read": "auth != null",
".write": "auth != null",
"items": {
".indexOn": "ownerId"
},
"events": {
".indexOn": "ownerId"
},
"contacts": {
".indexOn": "ownerId"
}
}
}
Based on the documentation, Do I simply need to do this?
{
"rules": {
".read": "auth != null && auth.uid == $uid"
".write": "$user_id === auth.uid",
"items": {
".indexOn": "ownerId"
},
"events": {
".indexOn": "ownerId"
},
"contacts": {
".indexOn": "ownerId"
}
}
}
Will users still be able to access their own (previously) written data prior to making the change while enforcing the security rules from Firebase.
Apologies if this a silly question, but got a lot of data which I cannot let users not have access to.
Thanks
As firebase documentation says:
Sometimes, Rules check that a user is logged in, but don't further restrict access based on that authentication. If one of your rules includes auth != null, confirm that you want any logged-in user to have access to the data.
So you have to get rid of this part down under the rules part:
".read": "auth != null",
".write": "auth != null",
And use any of these approaches: Content owner only, Path-delineated access or Mixed public and private access.
For example:
{
"rules": {
"products": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid",
".indexOn": ["creatorId", "isActive"]
}
},
"stores": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid",
".indexOn": ["creatorId", "isActive"]
}
},
"orders": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid",
}
},
}
}

allowing write to one Firebase child when not logged in

I have a childnode in my database
Posts --> tapCount.
My default Firebase rules only allow someone to write to a node under 'Posts' when they are signed in. However I need write access to just this one node 'tapCount' even when they are not signed in.
I'm having trouble getting a rule to help me do this. Any thoughts ? Thanks
{
"rules": {
".read": "auth != null",
".write": "auth != null",
"Posts": {
".indexOn": ["userId","category"],
"tapCount": {
".read": true,
".write": true
},
".read": true,
".write": "auth != null",
}
}

How prevent retrieve a child in same parent node?

I want to read all usernames from users parent node, because I'm using search feature in my app (if provided searchActive: true child in users node). But email need to be reachable only by owner.
I have just tried like below, but I'm still getting email. I'm worried about security not only email, What I'm missing and How Can I organize all of them?
"rules": {
"users": {
".read": "auth !== null",
"$uid": {
".write": "auth !== null && auth.uid === $uid",
".read": "auth !== null && auth.uid === $uid",
"username": {
".validate": "
!root.child('usernames').child(newData.val()).exists() ||
root.child('usernames').child(newData.val()).val() == $uid"
},
"email": {
".read": "auth.uid == 'facebook:'+$uid || auth.uid == $uid"
}
}
},
"usernames": {
".write": "auth !== null",
".read": "auth !== null"
},
First the reason why you can still access email is because rules cascade meaning when you set read to true for the parent node all the children can also be read. In your case:
"users": {
//Read is being set to true here for everything in this node
".read": "auth !== null",
"$uid": {
".write": "auth !== null && auth.uid === $uid",
//This will be ignored, since read was allowed already
".read": "auth !== null && auth.uid === $uid",
"username": {
".validate": "
!root.child('usernames').child(newData.val()).exists() ||
root.child('usernames').child(newData.val()).val() == $uid"
},
"email": {
//This will be ignored, since read was allowed already
".read": "auth.uid == 'facebook:'+$uid || auth.uid == $uid"
}
}
},
"usernames": {
".write": "auth !== null",
".read": "auth !== null"
},
I suggest you take some time to read all the documentation about firebase security. It can really help you avoid situations like this and perhaps give you some idea's about implementing a good security for your case.
A possible solution is to use a seperate username node where you store all the usernames for your search feature. You can use the rules to make sure everyone can read it but only the owner of a specific username can change it.

Resources