firebase rules, create an user PERMISSION_DENIED: Permission denied - firebase

I get PERMISSION_DENIED: Permission denied when try to create an user:
{
"rules": {
".read": true,
".write": "auth != null",
"users": {
"$uid": {
".read": true,
".write": "auth.uid == $uid",
".validate": "
newData.child('user').isString() &&
newData.child('user').val().length > 3
"
}
}
}
}
user is string, has more than 3 letters. But I think it has something to do with the id.
I create an user with createUserWithEmailAndPassword and try to insert it on database:
firebase.database().ref('users/' + userID).set({
username: username,
email: email
});
The userID is the id createUserWithEmailAndPassword returns...
Any ideas what is wrong?

You problem comes from the .validate part: with your rules you need to write a node as follows
firebase.database().ref('users/' + userID).set({
user: username, // <-- see here we have a user sub-node
email: email
});
Or you need to change your rules as follows:
{
"rules": {
".read": true,
".write": "auth != null",
"users": {
"$uid": {
".read": true,
".write": "auth.uid == $uid",
".validate": "
newData.child('username').isString() &&
newData.child('username').val().length > 3
"
}
}
}
}

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.

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",
}
},
}
}

Firebase Database Rules to match row

I am using a Firebase Realtime Database. I have the following data:
I also have the rules:
{
"rules": {
".read": "auth != null",
".write": "auth != null",
"chat": {
"$key": {
".read": "data.child('memberId1').val() === auth.uid && data.child('memberId2').val() === auth.uid",
".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"
}
},
The initial rule works perfectly:
".read": "auth != null",
".write": "auth != null",
Problem
The following 2 rules have no effect.
"chat": {
"$key": {
".read": "data.child('memberId1').val() === auth.uid && data.child('memberId2').val() === auth.uid",
".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"
}
},
As you can see, in order to test these rules, in the first rule, I have made an impossible condition of memberId1 and memberId2 both equal to the users uid. As a result I would expect it to fail.
If I remove:
".read": "auth != null",
".write": "auth != null",
and just have:
"chat": {
"$key": {
".read": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid",
".write": "data.child('memberId1').val() === auth.uid || data.child('memberId2').val() === auth.uid"
}
},
Then access is denied. Even if I change it to:
"data.child('memberId1').val() === 'h6qQg5YfQveTaCyBEXwDMSJPqwk1'
The following is also denied:
"chat": {
"Ko7w9XTtuRVN4p6CMp7": {
".read": true,
Question
How should I structure the rules to allow that a user may only access a row where their uid matches either memberId1 or memberId2?
Thanks
UPDATE
I have the following code:
findChats(): Observable<any[]> {
return this.af.database.list('/chat/', {
query: {
orderByChild: 'negativtimestamp'
}
}).map(items => {
const filtered = items.filter(
item => (item.memberId1 === this.me.uid || item.memberId2 === this.me.uid)
);
return filtered;
});
}
My question is similar to this one. I try the following with no success:
{
"rules": {
"chat": {
"$id": {
".read": true
}
},
Firebase rules are atomic. So if you try to read /chat (and thats what you are currently doing) it will only check the /chat branch rules. Since you dont have any rule in /chat it goes for the default thats is not giving access. Therefore, your rules would only be evaluated in case you were trying to read /chat/chatId.
One possible solution you could go for is to store a list of chats which each user is part of. So you can keep your current chat branch but store another branch in the database with the following structure:
user_chats: {
uid1: {
chatId1: true,
chatId2: false
}
uid2: ...
}
And rules:
"user_chats": {
"$uid": {
".read": "auth.uid === $uid",
".write": "auth.uid === $uid"
}
}
Then you could keep your chat rules like you already have them but first get the data from /user_chats/uid and then for each chatId retrieved you you will need to read on chat/chatId.

Firebase Database, different rule for each data data

in my Firebase application want to apply different RULES for different data.
ex: my data are
ContactUs
-Ksdasda4sd
name: "Ram"
email: "ram#gmail.com"
message: "Hello how are u"
HotelLocation
-Ksdaseeesd
name: "Hotel Name"
address: "Near Highway"
city: "Bangalore"
without login ContactUs data can be read write by public,where HotelsLocations can be read and write after login only.
on this configuration both need authentication.
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
can is it possible
This is the configuration.
{
"rules": {
"contactme" : {
".read": "auth != null",
".write": "true"
},
"HotelLocation" : {
".read": "auth != null",
".write": "auth != null"
}
}
}

Permission Denied from Firebase using curl and javascript

I have a Firebase with a security config like this:
{
"rules": {
"serviceproviders": {
".read": "auth != null",
".write": "auth != null"
},
"bookings": {
".read": "auth != null",
".write": true,
".validate": "newData.hasChildren(['phone', 'time', 'date', 'apikey'])",
"apikey": {
// only allow valid apikey
".validate": "root.child('serviceproviders/' + newData.val()).exists()"
}
},
"status": {
".read": "auth != null",
".write": true
}
}
}
The idea is that users can only post /bookings/ with a valid apikey, that is, an apikey that can be found in /serviceproviders/.
In the Firebase simulator, this works as expected. However, when I use curl from the terminal, or Javascript from a html page, I get error: permission denied back from Firebase. I send exactly the same data (copy & paste).
My curl command looks like this:
$ curl -X POST -d '{"phone":"004512345678", "date":"2014-07-31","time":"10:00","apikey":"AA227D80-122C-4E5D-AEDF-24A829FA6403"}' https://example.firebaseIO.com/bookings/.json
And I get back:
{
"error" : "Permission denied"
}
OK, so after many hours of pulling my hair, I realized that in the guide on Firebase.com, the ".validate" rules are inside a block denoting the ID under that path, thus:
{
"rules": {
"serviceproviders": {
".read": "auth != null",
".write": "auth != null"
},
"bookings": {
".read": "auth != null",
".write": true,
"$bookings_id": {
"apikey": {
// only allow valid apikey
".validate": "root.child('serviceproviders/' + newData.val()).exists()"
},
".validate": "newData.hasChildren(['apikey','date','time','phone'])"
}
},
"status": {
".read": "auth != null",
".write": true
}
}
}
works as expected, because of the "$bookings_id" block.

Resources