So I am assuming that my firebase rules are insecure :
I need second thoughts on it
below I set rules like:
Anyone can read and create(register)
Registered users can read messages
Registered users can create messages
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /usernames/{usernames} {
allow read;
allow create;
}
match /users/{users} {
allow read;
allow create;
}
match /messages/{messages} {
allow read;
allow create : if request.auth.uid != null;
}
}
}
Anyone can read and create(register)
match /users/{users} {
allow read, write: if true;
}
Registered users can read messages (and No one can write it)
match /users/{users} {
allow read: if request.auth.uid != null;
allow write: if false;
}
Registered users can create messages (and No one can read it)
match /messages/{messages} {
allow create: if request.auth.uid != null;
allow read: if false;
}
Related
Now that firebase has forced using rules scrambling to find the right solution here.
I have all images in the main bucket and every user once logged in has something like
bucket
users/{uid}/uploads
where all there uploaded photos go (would be cool to restrict to images at some point)
these should be public read and write, if write can be only for the authenticated user even better, but auth to read is necessary.
there is a special folder before a user is authenticated and need upload a profile pic
users/uploads
which should be read write to the public here is what i have but the second rule takes precedence
service firebase.storage {
match /b/{bucket}/o {
match /users {
match /uploads {
match /object {
allow read, write
}
}
}
match /{allPaths=**} {
allow read, write: if request.auth != null
}
}
}
I'm thinking it probably needs to be a not /users/uploads forthen then do do this but the documentation is bad for if else statements. any thoughts?
EDIT: this rule set works for reading correctly but still can't write when unauthenticated during sign up
service firebase.storage {
match /b/{bucket}/o {
// Allow only authenticated users to upload
// Any user can read
match /users/uploads {
allow read, write;
}
// Only allow user with auth.uid == uid to read/write
match /users/{uid}/uploads {
allow read: if true;
allow write: if request.auth.uid == uid;
}
}
}
You can try the following rules that'll restrict access to user's own directory and also have a public folder:
rules_version="2";
service firebase.storage {
match /b/{bucket}/o {
// Allow only authenticated users to upload
// Any user can read
match /users/uploads {
allow read: if true;
allow write: if request.auth != null;
}
// Only allow user with auth.uid == uid to read/write
match /users/{uid}/uploads {
allow read: if true;
allow write: if request.auth.uid == uid;
}
}
}
Do note that if request.auth != null; allows everyone write (including delete) so try using allow create: only.
I have a collection structure like this.
products {
123456 : {
stock_qty : (Number)
}
}
I want to validate stock quantity to be positive. I have applied following firebase security rule.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if request.auth.uid != null;
allow write: if request.auth.uid != null;
}
match /products/{document=**}{
allow write: if request.resource.data.stock_qty > 0;
}
}
}
But Still I am able to add products with negative stock_qty.
what I am doing wrong here?
You need to remove this part of your rules:
match /{document=**} {
allow read: if request.auth.uid != null;
allow write: if request.auth.uid != null;
}
This allows all authenticated users to read and write your entire database, regardless of any other rules you have defined.
If any rule gives access to a document, another rule cannot revoke that access.
If you have other queries for other collections that must be protected, you will need rules for those other collections as well.
I have the following rules in my Firestore database. But I still keep getting a notification from Firestore that the rules I set in my database are not secure. Please see the codes below. Any suggestions or recommendations to make the database more secure?
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if true;
allow write: if userIsAdmin();
}
match /Basket/{Basket} {
allow read, update, delete: if userOwnPost();
allow create: if request.auth.uid != null;
}
match /AllOrders/{AllOrders} {
allow read, create, update: if userOwnPost();
}
match /Items/{Items} {
allow update: if userOwnPost();
}
match /Voucher/{Voucher} {
allow update: if userOwnPost();
}
match /User/{User} {
allow read, update: if userOwnPost();
allow create: if request.auth.uid != null;
}
function userIsAdmin() {
return getUserData().userRole == 'Admin';
}
function getUserData() {
return get(/databases/$(database)/documents/User/$(request.auth.uid)).data;
}
function userOwnPost() {
return getUserData().objectId == request.auth.uid;
}
}
}
You have some overlapping match statements in your rules:
With
match /{document=**} {
allow read: if true;
allow write: if userIsAdmin();
}
you allow read access on all documents in your Firestore database.
As explained in the doc (section "Overlapping match statements"), "in the case where multiple allow expressions match a request, the access is allowed if any of the conditions is true".
So all your other security rules are just overlapped by this one.
I am struggling with the firebase security rules, I can get parts of it to work, but when I try to connect it all together I am having issues.
I would like to have my rules do the following:
Allow read to all documents if authenticated
Allow create or update user document by authenticated only at document /databases/$(database)/documents/users/$(request.auth.uid) but not add admin to the roles array
!("admin" in getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles)
Allow only getRole(“admin”) == true to create, edit, or delete any user document and any other document
function getRole(role) {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny([role]);
}
Here is what I have that does not include the users being able to create their own user account. It works to allow only admin to write any document.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function getRole(role) {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny([role]);
}
match /{document=**} {
allow read: if true;
allow write: if getRole('admin') == true;
}
}
}
Here is what I tried to add to allow users to create their user document. It seems to be not cascading to the next rule, it tries the getRole in the match /{document=**} path and finds that the user is not an admin so it fails. I have tried reordering and placing the /users/ path above and it goes thru that path fine then does the same thing and fails on the getRole in the /{document=**} path again. I also tried specifying the document names rather than using the wildcard and that seems to not allow any get or write. Can you please point me in the right direction?
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function getRole(role) {
return exists(/databases/$(database)/documents/users/$(request.auth.uid)) && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny([role]);
}
match /{document=**} {
allow read: if true;
allow write: if getRole('admin') == true;
}
match /users/{userId}{
allow read: if request.auth.uid != null;
allow create: if getRole('admin') == true || request.auth.uid == userId &&
!(getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny(["admin"]));
allow update: if getRole('admin') == true || request.auth.uid == userId && exists(/databases/$(database)/documents/users/$(request.auth.uid)) == true && !(getAfter(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny(["admin"]));
}
}
}
It turns out that I can't allow admin to dynamically create collections that are not defined in the security rules unless I use the match /{document=**} which applies those rules to every path and is not the desired result. I was able to get the rules setup to accomplish the other parts pretty easily as follows:
service cloud.firestore {
match /databases/{database}/documents {
function getRole(role) {
return get(/databases/$(database)/documents/users/$(request.auth.uid)).data.roles.hasAny([role]);
}
match /users/{userId} {
allow read: if request.auth.uid != null;
allow create: if request.auth.uid == userId && request.resource.data.roles.hasAny(["admin"]) == false;
}
match /collectionName/{collectionNameId} {
allow read: if request.auth.uid != null;
allow write: if request.auth.uid != null && getRole('admin') == true;
}
}
}
Setup multiply rules for firebase.
Example with 3 database collections.
Cloud Firestore
On firebase collection of countries, all users should be allowed to read and write.
On firebase collection of cars, only admins are allowed to write.
On firebase collection of airplanes, all authenticated users are allowed to write.
not working documentation:
https://firebase.google.com/docs/rules/basics#cloud-firestore
how to setup rules with correct syntax?
// All public to include countries
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if true ;
allow write: if true ;
}
}
// check cars collection
match /databases/{database}/documents/Cars {
// For attribute-based access control, Check a boolean `admin` attribute
allow read: if true ;
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
}
// check airplanes collection
match /databases/{database}/documents/Airplanes {
// Allow only authenticated content owners access
match /{database}/{userId}/{documents=**} {
allow read: if true ;
allow write: if request.auth.uid == userID
}
}
}
You have a few mistakes in your rules.
You have a statement that allows everyone to write every document. When there is more than one match statement that matches the current request, and one of the statements allows the request, the final verdict is ALLOW. Remove the foloving:
match /{document=**} {
allow read: if true ;
allow write: if true ;
}
Firestore is case sensitive. To avoid mistakes, use consistent naming convetion like camelCase or pascal_case.
You have to add a document match variable at the end of match statement
This should work:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read: if true;
allow write: if request.auth != null && request.auth.uid == userId;
}
match /cars/{carId} {
allow read: if true ;
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
}
match /airplanes/{airplane} {
allow read: if true ;
allow write: if request.auth != null ;
}
}
}