Firebase storage rules, leave on path open - firebase

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.

Related

Firebase, insecure rules

I recently received an email from firebase telling me that the rules of my database (Firestore) are insecure so I changed them to the following:
rules_version = '2';
service cloud.firestore {
match / databases / {database} / documents {
match / {document = **} {
allow read: if true;
allow write: if request.auth.uid != null;
}
}
}
Before I had these rules:
allow read, write: if true;
After making the change, the emails keep coming back and I don't know what else to do.
I already tried several of the following options given in this link but none of them works for what I need.
https://firebase.google.com/docs/rules/insecure-rules#firestore
I need authenified users to be able to read and create content. So use the rules that I put above.
I saw that in the email they send me it says that people can modify my database, is this referring to from the app, or does it mean that they can hack me or something?
Because the end of my app is that users can create content.
But I don't want someone to hack into my database and delete everything, is that possible?
Thanks
The emails are because the rules aren't really stringent. You should probably be using the following rule, that:
Allows unauthenticate users to read data
Allows authenticated users to create entries
Allows to update & delete entries that are only owned by themselves and not of others.
service cloud.firestore {
match /databases/{database}/documents {
// Allow public read access, but only content owners can write
match /some_collection/{document} {
allow read: if true
allow create: if request.auth.uid == request.resource.data.author_uid;
allow update, delete: if request.auth.uid == resource.data.author_uid;
}
}
}
Read this article for better understanding. You can also check when firestore flags rules as insecure over here. More importantly, this is the point to be emphasized.
Remember that Firebase allows clients direct access to your data, and
Firebase Security Rules are the only safeguard blocking access for
malicious users. Defining rules separately from product logic has a
number of advantages: clients aren't responsible for enforcing
security, buggy implementations will not compromise your data, and
most importantly, you're not relying on an intermediary server to
protect data from the world.
Sample rules:
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userDoc} {
allow read: if true
allow create: if request.auth.uid == request.resource.data.id;
allow update, delete: if request.auth.uid == resource.data.id;
}
match /posts/{postDoc} {
allow read: if true
allow create: if request.auth.uid != null;
allow update, delete: if request.auth.uid == resource.data.user_id;
}
match /comments/{commentDoc} {
allow read: if true
allow create: if request.auth.uid != null;
allow update, delete: if request.auth.uid == resource.data.user_id;
}
}
}
This case is mentioned in the documentation. Any authenticated user can write to your database and that also involves deleting data. You are using a recursive wildcard which gives them access to complete database.
Instead try rules that allow users to write their own documents only or something similar.
rules_version = '2';
service cloud.firestore {
match / databases / {database} / documents {
match /collectionName/{docId} {
allow read: if true;
allow write: if request.auth != null && request.auth.uid == docId;
}
}
}
Above example will allow users to edit documents where document ID is equal to their UID only.
If you wish to allow selected users to write (such as admin) then you can add a field namely admin and set it to true in user's document in users collection. Then you can read the document data as shown:
match /collection/{document} {
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
allow read: true;
}

Firebase Rules check

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;
}

How can I modify Firebase Storage Rules

I'm storing images under uid/PropertyPhotos/Property# (where # is incremented as images are uploaded). The uid belongs to the user that posted the image, not the current logged on Firebase user. What I'd like is to allow anyone to view those images. How do I modify the storage rule below to allow that?
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
// we want anyone to view the property images (no auth, publicy readable)
match /{uid}/PropertyPhotos {
allow read;
}
}
}

How can Firestore check a collection to allow write (rules)

I use a collection called "admin" in Firestore to define which users can write new documents (image below).
At moment, it is controled just by software. I would like to add rules to Firestore. I tried the rule below but it didn't work. What would be the correct rules in that case ?
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if request.auth != null;
allow write: if get(/admin/{anyDocument}).data.userId == request.auth.uid;
}
}
}
I'd recommend instead having a users collection with an admin field that can be set to true/false. Then you can do something like:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if request.auth != null;
allow write: if get(/users/${request.auth.uid}).data.admin == true;
}
}
}
As far i know this is not possible with your current database structure. Because the push key is not accessible in firestore rules unless it is with in the admin node.
One way is to save the admin with their uid as key like admin/userID/data...
now you can access it
allow write: if get(/databases/$(database)/documents/admin/$(request.auth.uid)).data.userId == request.auth.uid;;

How do I restrict writes to a document owned by a user in Firestore?

I have some articles.
Each article has a reference field to the profile document of the author who wrote that particular article.
Auth'd users (using Firebase's Auth) will be associated with these profiles.
How do I make these articles editable by the currently logged in user only if that user owns the article?
In Firestore's documentation, there is a recurring example:
service cloud.firestore {
match /databases/{database}/documents {
// Allows you to edit the current user document (like a user's profile).
match /users/{userId} {
allow read, write: if request.auth.uid == userId;
}
// Allows you to read/write messages as long as you're logged in (doesn't matter who you're logged in as, so theoretically you could change other peoples' messages 👌).
match /rooms/{roomId} {
match /messages/{messageId} {
allow read, write: if request.auth != null;
}
}
}
}
Where is the example for how to structure and edit a document owned by a certain user?
Assuming you have a document with e.g. owner: <uid> stored in it, you can do:
service cloud.firestore {
match /databases/{database}/documents {
match /somecollection/{id} {
allow write: if resource.data.owner == request.auth.uid;
}
}
}

Resources