Firebase Storage Rules with Firestore not working - firebase

I am trying to upload images with Firebase Storage JS SDK with some rules based on Firestore data.
imageList.forEach(element => {
tasks.push(firebaseStorage.child("Devices").child(dateTime).child(element.name).put(element, { contentType: element.type }))
});
Rules:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /Devices/{deviceId} {
// Authentication is required.
allow create: if request.auth.uid != null &&
// Only Admins are capable of uploading images.
firestore.exists(/databases/(default)/documents/Admins/$(request.auth.uid));
// Authentication is required.
allow read: if request.auth.uid != null &&
// Only Cashiers are capable of reading images.
firestore.exists(/databases/(default)/documents/Cashiers/$(request.auth.uid));
// No update or deletion of files in client (web) for now.
allow update, delete: if false
}
}
}
This is what I get. Any idea what went wrong here? TIA.
Is read and write permission are both required for uploading?

The match /Devices/{deviceId} matches is applied for the files in /Devices directory only. If the rule must be applied to a file within the deviceId sub directory then the path must be:
match /Devices/{deviceId}/{fileName} {
// ...
}
If a rule must be recursively applied to all sub directories, then use a wildcard:
match /Devices/{device=**}

Related

Firebase storage rules: authenticate the allowed user

I have a channel for communication between two users and I use Firebase storage to transfer files between these users.
I don't want a third user to have access to the channel's files.
I'm trying to identify authorized users using 'authfile' and the metadata inside it.
That authfile is uploaded using admin sdk.
Only specific users can download and upload files to specific path in storage where the authfiles metadata contains his uid. still the users are not allowed to touch the authfile.
The metadata inside the authfile looks like this:
metadata: {
AvnYaUFdaJh1j0FMIiKWoIC2MDw1: true, // firebase userId 1
YhFyYRbutlf1PFI4NLKTN4qWRhQ2: true, // firebase userId 2
}
my storage
The rules I've tried:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// Channel Media
match /media/{channelId}/{allPaths=**} {
function isAllowedUser(uid) {
return /authfile.resource.metadata.users[uid] == true;
}
allow delete: if isAllowedUser(request.auth.uid)
&& request.resource.contentType != 'authfile'
allow read: if isAllowedUser(request.auth.uid)
&& request.resource.contentType != 'authfile'
allow write: if isAllowedUser(request.auth.uid)
&& request.resource.contentType != 'authfile'
&& request.resource.size < 16 * 1024 * 1024;
}
}
}
I am writing Firebase storage rules for the first time and would like advice on how this could be implemented.
I don't think you need 'users' here.
function isAllowedUser(uid) {
return /authfile.resource.metadata.users[uid] == true;
}
This should be valid
resource.metadata[uid] == true;
Additionally, if you need something like checking existence of another file or it's metadata, consider using Cloud functions as mentioned in this answer.

Should I use Firebase anonymous login to secure my data? [duplicate]

I'm developing an app that doesn't require logging in because there isn't any user-specific data. My original plan was to just make my entire database be read only. However, upon doing some research, I found that those security rules would leave my database very vulnerable. My new plan is to implement anonymous authentication for each new user that opens my app and then delete that user once they exit my app. The security rule would be just to allow reading if the user is authenticated. Is this enough to prevent someone from using abusing queries to my database?
Generally, No.
Solely using anonymous authentication adds a hurdle to accessing your database and will protect it from simple read queries as if your database was fully open, but you should combine that with security rules that limit the queries that can be performed.
Assuming we are starting with these barebone rules:
// Allow read access on all documents to any user signed in to the application,
// and write access to only administrators
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read: if request.auth.uid != null;
allow write: if request.auth.token.isAdmin === true;
}
}
}
To tighten up your rules, you should first remove the wildcard entry and replace them with fixed document paths.
// Allow read access on all documents at /posts/{postId} to any user signed in to the application,
// and write access to only administrators
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postId} {
allow read: if request.auth.uid != null;
allow write: if request.auth.token.isAdmin === true;
}
}
}
or even
// Allow read access on all documents at /posts/{postId} to any user signed in to the application,
// and write access to only administrators
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postId} {
allow read: if request.auth.uid != null;
allow write: if request.auth.token.isAdmin === true;
// allow same permissions on subcollections of /posts/{postId}
match /{document=**} {
allow read: if request.auth.uid != null;
allow write: if request.auth.token.isAdmin === true;
}
}
}
}
Next you should consider adding rules that limit the size of queries performed against your database using the granular security rule list as described in Securely query data of the Firebase Documentation.
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /posts/{postid} {
// Deny any query not limited to 10 or fewer documents
allow list: if request.auth != null
&& request.query.limit <= 10;
// Anyone can retrieve an individual post
allow get: if request.auth != null;
// Only an admin can write to posts
allow write: if request.auth.token.isAdmin === true;
}
}
}
Depending on how frequently the data is updated, you may also consider storing data bundles on Firebase Storage or you could even serve the data from Firebase Hosting where they can be served by a CDN instead of your application.

How to configure the rules of a Firebase project to be safe?

Hi I have the Firebase project, and when I create the databases, I create some rules for testing.
Now, they expire, and they close my project.
It is my first time working with Firebase projects, and I have no experience. I show you how I have defined the rules for both Cloud Firestore and the Realtime Database.
The project is an application in which users can register and leave their comments.
How should I set the rules for my databases to be secure?
How should I write my rules code?
I was absent from my project for a few days and they wrote to me from Google, which closes my project in two days. I have looked for information, but I do not know how to create the rules so that they are correct and my project also works
I EDIT MY QUESTION to add details
In my application I only want registered users to be able to write comments.
The alert that Firebase shows me is the following:
"Its security rules are defined as public, so anyone can steal, modify or delete data from its database."
The databases are empty, so there are no records yet.
Can you help me? Firebase will close my project if I don't write the rules right, the rules shouldn't be public.
I read the documentation that Firebase offers, but I don't really understand how to create my rules.
They show something like this, for authenticated users:
// Allow read/write access on all documents to any user signed in to the application
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
And on the other hand they show these rules:
**// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this rule set in production; it allows
// anyone to overwrite your entire database.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}**
I don't know which one I should use exactly, and how I should write them, so that in my React Native app users can leave feedback.
Can you help me ?
I show the code of the rules of my databases
//REALTIME DATABASE
{
"rules": {
".read": true,
".write": true
}
}
//CLOUD FIRESTORE
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// This rule allows anyone with your database reference to view, edit,
// and delete all data in your Firestore database. It is useful for getting
// started, but it is configured to expire after 30 days because it
// leaves your app open to attackers. At that time, all client
// requests to your Firestore database will be denied.
//
// Make sure to write security rules for your app before that time, or else
// all client requests to your Firestore database will be denied until you Update
// your rules
match /{document=**} {
allow read, write: if request.time < timestamp.date(2020, 9, 2);
}
}
}
You can use the following rule where only authenticated users can write and read to the database.
For Cloud Firestore:
// Allow read/write access on all documents to any user signed in to the application
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}
For Realtime Database:
// Only authenticated users can access/write data
{
“rules”: {
“.read”: “auth != null”,
“.write”: “auth != null”
}
}
Speaking through experience, there are two main ways of securing your data:
Set a field in the document such as "userID" and only allow CRUD when the auth.uid value matches this field.
Use the collection-document-collection nature of cloud firestore and write a rule where you allow a user to CRUD all of their own collection. E.g.
match /users/{userID}{
allow read: if request.auth.uid ==userID;
allow write: if request.auth.uid == userID;
match /userDocs/{docID}{
allow read: if request.auth.uid == userID;
allow write: if request.auth.uid == userID;
}
}
Ideally you need to allow only authenticated users to access resource. From you code above
{
"rules": {
".read": true,
".write": true
}
}
The above will allow anybody to read and write to the database even to unauthenticated users.
for firestore as you can see the rules state that it should only allow full priviledge read and write to cloud firestore if only the date has not passed (2020,9,2)
VISIT the link To learn more about firebase database rules
and visit
to learn about firestore rules
You can use firebase authentication for your users then if they are authenticated they can access the database.

How can i Allow user to modify Own Files only Firebase Storage?

I am using Firebase Storage to store files of the user. My storage structure is as shown below. I want to allow only created file user to modify his files not to others.
profiles/uid/posts
posts/ folder contains all his uploaded files. I want to restrict between this path files from other users modification. They can see my all files between profiles/uid/posts this path. My current rules are:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Help me to achive this. Thanks
Identify the per-UID folder like this:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /profiles/{uid}/posts/{allPaths=**} {
allow read, write: if request.auth.uid == uid;
}
}
}
I strongly suggest reading more about per-user authentication rules in the documentation.

Access url without token in Firebase Storage

I have a firebase storage download url, like
https://firebasestorage.googleapis.com/v0/b/siren-5eee7.appspot.com/o/profile%2FC6jNlR0F4cZBPv7wF0REWUNVor33?alt=media&token=63a9130e-2ba6-4f38-ac3f-2231c54a1043
How can I access this url without token parameter?
For example, If I access above url without token there will be 403 error showing permisson denied.
My firebase storage secure rule is below :
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
This file located in /etc file. How can I do it?
Try changing rule:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read;
allow write: if request.auth != null;
}
}
}
In case you need the rule to allow accessing only the images without a token you have to do the following:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read: if request.auth!=null || resource.contentType.matches('image/.*');
allow write: if request.auth!=null;
}
}
}
From what I understand, you're trying to make the whole bucket publicly available. Using Firebase access rules might not be best, you might want to make the bucket read access available via Google Cloud's Storage layer.
To do that, one of the easiest way is using the Google Cloud Console Storage.
Select the bucket, click the bucket to configure and open the permissions tab.
Since this is Firebase managed bucket, it would have what Google called fine-grained access control. Don't worry, adding public access is quite simple.
Click Add members button, then, on the sidebar, add in allUser as new member, and give it the role of Storage > Storage Object Viewer. You can see more detail in the Storage Docs.
This will make the bucket publicly viewable via <bucketname>.storage.googleapis.com.
If you created extra bucket in Firebase that match a domain you own and verified in Google Search Console, you can create a bucket of named after your custom domain and have it publicly accessible using a CNAME of the custom domain that points to c.storage.googleapis.com. You can see more detail at Storage Endpoints Docs, Google Cloud's docs explain it much better than I can. Hope this helps!
If you need to access to certain url (image) without token parameter use the rule below:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /images/users/default.png {
allow read;
}
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
If you need to access to certain folder without token parameter use the rule below:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /images/{wildcardpath=**} {
allow read;
}
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Note: Change the url or folder to yours

Resources