Firebase storage rule for authenticated user not working - firebase

When I open my Firebase Storage bucket and go to files I have the following folder structure:
/<environment>/reports/<userId>/
I want that only the authenticated userId is allowed to read, write the reports in that user folder.
I tried the following, but it gives me the message that access is denied. What am I doing wrong? I copied almost one-to-one the example from the docs.
// Grants a user access to a node matching their user ID
service firebase.storage {
match /b/{bucket}/o {
// Files look like: "<ENVIRONMENT>/reports/<UID>/path/to/file.txt"
match /production/reports/{userId}/{allPaths=**} {
allow read, write: if request.auth.uid == userId;
}
}
}

You can use the rules simulator in the Firebase Storage Console to test your rules. I've tested yours and they seem to be working OK:
You'll need to remember to specify a final node name such as /production/reports/{userId}/test in order for the rule to work, as it will match the storage bucket filename rather than the parent directory due to /{allPaths=**}.

Related

Why am i getting firestore alerts -> Your projects cloud firestore database "default" has insecure rules

I want unlogged users of my reactjs webapp to be able to read only "business profile collection".
I have the following db structure.
And the following rules:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read : if true;
allow write: if request.auth != null;
}
}
}
I am quite new to the firestore rules, i have multiple ways and this is the only one that worked for me.
The user Dharmaraj previously mentioned that your rules are allowing any user to read and write to any collection of the database, something you can validate using the rules playground. If that is the desired behavior, then you can ignore these alerts.
However, you said you wanted unlogged users of your app to be able to read only “business profile collections”. You can read the Production-ready rules and its sections, then use the one that is best for you. The way I see it, you should read and use the Attribute-based and Role-based access section and finish with something like this:
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, Check a boolean `admin` attribute
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
allow read: true;
// Alternatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
}
}
}
Although, you might want to check them and read them carefully to see if any other option is more suitable for you. I will add the Security Rules language that is needed to understand what your rules are doing and how to Fix insecure rules.

Why is Firebase Storage "rules_version = '2'" getting overriden?

I've appended the following line to my storage rules following the docs:
rules_version = '2';
Furthermore, my rules are now:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Moreover, I am able to list out the files of a folder using listAll which is an exclusively version 2 feature.
However, each day I come back to my dashboard to find my rules updated to the previous version, being:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
How and why does this happen? More importantly, how may I fix the issue?
With the help from Jonathan from Firebase who was kind enough to remind me of the fact that I am deploying almost on a daily basis I figured out what was going wrong. It turned out that as part of my continuous deployment I was also deploying Firebase storage rules, hence I was indirectly the one overriding my own rules.
Now the obvious and easy solution is to just update the storage.rules file locally.
There are only three ways your rules can change:
Using the Firebase console
Using the Firebase CLI to deploy rules from a local file
Use the Firebase Admin SDK.
If your rules are changing and you are absolutely certain that it's not coming from one of these two methods, contact Firebase support for assistance.

Firestore Permission denied in production Electron app but requests go through in development

I have added multiple rules to my Firestore database. When I test the app in development mode, everything works as it should but for some reason when I build and run the app for production all my requests are denied with "Missing or insufficient permissions."
I cannot allow anyone to read, and the documents. The rules are vital and I am not sure that they are the problem anyway. I have used the Firestore simulator to test calls, as well as the emulator.
I am building with the command:
electron-builder build --win --x64
The rules
match /databases/{database}/documents {
function owns(id) {
return request.auth.uid == id;
}
match /{userId}/{document=**} {
allow read, write: if owns(userId);
}
}
load(collectionName) {
const uid = firebase.auth().currentUser;
let collection = uid &&
firebase.firestore().collection(uid).doc("data").collection(collectionName);
}
return collection.get();
}
Basically the top level of the database is the user ids, and a user can access collection within their top-level collection.
This was due to an issue in firebase-js-sdk
The corresponding issue is here:
https://github.com/firebase/firebase-js-sdk/issues/1491

Allow anonymous user to write to firebase firestore

I want to allow links inside my application looking like:
mywebsite.com?u=nc27ri3ucfyinyh3
where nc27ri3ucfyinyh3 is a uuid, so the link can be sent to an anonymous user. The anonymous user should be able to view the page (database read), but it should also log to the database that they've viewed that link (database write).
As we get a warning when our firestore rules look like
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write;
}
}
}
as it is not secure.
Your security rules are defined as public, so anyone can steal, modify or delete data in your database
How should we handle the case of these anonymous users?
The first thing is that you could write a more restrictive set of rules than you have there (for example, restrict writes to just one collection (by changing the match /{document=**} line to something more restrictive (e.g. just the links collection or something). This, of course, still effectively allows anonymous users the full run of your database, but only within that collection.
Additionally, you can add validation to the incoming request via the request.resource object) -- its likely due to the anonymous nature of the user that you will still have a relatively insecure set of rules.
The data validation approach can look at both the current state of the database (in resource.data) as well as the contents of the incoming request (in request.resource). Here is the reference documentation for Resource and Request objects.
Here is an example rule that assumes these documents:
Exist in the /uuids collection
Are created by some other method (authenticated user, admin API, etc)
Only need to be fetched by ID, not queried as a set.
Only have 2 fields: content and visits
visits must be an integer, and is only allowed to be incremented
When the document is created, visits is initialized to zero.
I have not extensively tested these rules, only used the simulator to confirm they behave roughly as expected, I recommend you write extensive tests for any rules you intend to deploy. In particular, I am not certain about the behavior of the test for only being incremented when the document is under heavy contention.
rules_version = '2';
function notUpdating(field) {
return !(field in request.resource.data)
|| resource.data[field] == request.resource.data[field]
}
service cloud.firestore {
match /databases/{database}/documents {
match /uuids/{uuidValue} {
allow get: if true;
allow update: if (request.resource.data.keys().size() == 2 &&
notUpdating('content') &&
request.resource.data['visits'] == int(request.resource.data['visits']) &&
request.resource.data['visits'] > 0 &&
request.resource.data['visits'] == resource.data['visits'] + 1);
allow write: if false; // these 4 lines can also just be omitted
allow list: if false;
allow delete: if false;
allow create: if false;
}
}
}
This would allow you, for example, to ensure that only exactly the field you want is being touched, and only with valid data (e.g. positive integers or similar).
Remember -- the security rules are your only protection -- users can run arbitrary code against the database within those rules, not just code that you have given them. So, for example, if they can blanket read the collection, they can literally read the entire set of documents in that collection.
Alternatively, it might instead make sense to write an http, https, or callable cloud function that does exactly what you need -- register that the link has been used via a write, and then redirect or serve the necessary data itself. This gives you a lot more control over the specific write, but it does come with some added cost. The advantage here is that you wouldn't need to allow any public or open access to the database at all.
Cloud functions can also be served off of mywebsite.com if that web site is hosted on Firebase Hosting, via rewrite rules.

Firebase storage link Permission denied

I'm getting the URL with getDownloadURL after i put the url inside a img tag but i get this error
the rules of the storage are these:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
So everybody should be able to read, so i can't understand :(
somebody can help?
This may be due to a missing permission. You need to check whether you have
firebase-storage#system.gserviceaccount.com
as a member with a "Storage Admin" role. If you don't have one, then add it. That would fix the issue.
Here are the steps on how you can check and add permissions.
Go to Cloud console
Navigate to Storage
Select your bucket then click show info panel.
You can also add the missing permission in the IAM & Admin if you want.
If it is not the problem then you are getting the error due to the some problem in the code, you may want to check it once more.

Resources