Firebase storage security rules bypassed if downloading via a URL? [duplicate] - firebase

This question already has answers here:
Firebase Storage read security rules don't seem to be having any effect
(1 answer)
Firebase storage file is accessed by everyone
(1 answer)
Closed 2 months ago.
If downloading via URL, I can see that even unauthenticated users can download images stored in my Firebase storage instance, despite me having set restrictive rules for these.
Is that intended?
The link above seems to suggest that in order to enforce storage security rules I will have to use other functions:
From version 9.5 and higher, the SDK provides these functions for
direct download:
getBlob()
getBytes()
getStream()
Using these functions, you can bypass
downloading from a URL, and instead return data in your code. This
allows for finer-grained access control via Firebase Security Rules.
Can someone confirm that this is the way to go to have my rules enforced?

A download URL provides public read-only access to the file and is indeed not affected by the security rules you set.
If you want to enforce the security rules, your users will have to download the file through the SDK instead of through download URLs.

Related

Firebase security rules for public read without authentication [duplicate]

This question already has answers here:
Firestore Security rules without Authentification
(3 answers)
Firestore security rules without auth
(1 answer)
How do we secure a Firebase Firestore without using Firestore Authentication? Or is it a must?
(1 answer)
Closed 3 days ago.
I have made an app which show pdf files and some data which are store in firestore database. And no need to signup or login to read the data through app. But I am getting mail from firebase to update security rules and I have no ideas about firebase security rules.
Can you suggest me the secure rules for firestore database so that user can able to read the data but can't allow to perform write operation.
You should first read the documentation on security rules. There is plenty of information out there to use as a guide, especially the basic rules.
You will have to give read access to each collection individually in order to avoid getting the warning email. Taking the pattern from the linked documentation, if the collection you want to give access is named "cities":
match /cities/{city} {
allow read;
}
Since we don't know the names of your collections, we can't tell you exactly what to do.

Getting a client URL to Firebase Cloud Storage that comply with storage rules

I have a web application on Firebase where I create a Firestore document with a reference to a Firebase Storage file.
I've setup rules on Firebase Storage to only allow read: if request.auth != null.
Since Firestore complies with similar rules I am able to ensure that access to my Firestore document is only possible, when a user is authenticated, but how do I best about enforcing the same rule in my web application to the Firebase Storage file?
I can use getDownloadUrl() when I've uploaded the file and store the URL in my Firestore document. - But URL is always public to anyone
I can create a Firebase Function that on each request checks authentication and if authenticated, generate a getSignedUrl() with an expiration of say 5 minutes and then do a 302 redirect to the temp public URL - but that does not comply with Firebase Storage rules so I need to replicate any new rulesets in the function
Why can't Firebase Storage not simply behave like Firestore and check the auth on a http request and return the file is it complies with rules?
Am I totally missing a 3) and better option to make sure a user is logged in before accessing a file from storage?
According to the Cloud Storage for Firebase Documentation you can now access files through the Web SDK.
From version 9.5 and higher, the SDK provides these functions for
direct download:
getBlob()
getBytes()
getStream()
Using these functions, you can bypass
downloading from a URL, and instead return data in your code. This
allows for finer-grained access control via Firebase Security Rules.
I can use getDownloadUrl() when I've uploaded the file and store the URL in my Firestore document. - But URL is always public to anyone
It may not be very clear from the documentation, but that's exactly the way download URLs were designed to work.
Why can't Firebase Storage not simply behave like Firestore and check the auth on a http request and return the file is it complies with rules?
It behaves like that when you use the provided client SDK to download files (not using download URLs). Unfortunately, the web SDK doesn't have a file download API (while Android and iOS do).
If you would like to file a feature request for the web SDK, that should go to Firebase support. For now, you have to use download URLs, which are publicly accessible. Or you can create your own backend endpoint that verifies an auth token provided by the client using the Firebase Admin SDK. The backend code can decide if the user should get be able to get the file contents.

How can one restrict Firebase Admin SDK to delete data from firebase database [duplicate]

This question already has an answer here:
Is there a way to add security rules that apply to admin in Firebase?
(1 answer)
Closed 4 years ago.
I have firebase rules to restrict users from accessing certain part of my firebase databases, but how can I restrict the user initialized with Firebase Admin SDK to delete my firebase database nodes?
Thank You
When accessing Realtime Database using the Admin SDK, it has unrestricted access to your database by default. Security rules don't apply.
The only way to restrict the Admin SDK is to initialize it with UID that forces it to behave as if it authenticated as user with that UID. This is described in the documentation using databaseAuthVariableOverride. There is also another answer on SO that describes what to do for nodejs. If you scope access like this, your security rules will have to specifically call out that UID in the rules to limit its access.

What do firebase cloud-storage read access rules apply to? SDK, URL http get, or both?

I'm new to firebase cloud storage. Quick question: Are firebase cloud-storage read rules meant to apply to SDK read access, or http (get) URL access (via the URL returned by the SDK after a write), or both?
May have followup questions depending on how this question is answered.
Thanks.
The Firebase security rules for Cloud Storage apply to users accessing Cloud Storage through the Firebase SDK.
The rules do not apply to users accessing Cloud Storage through a download URL, which is an unguessable URL that provides read-only access to files.
The rules also do not apply to users accessing Cloud Storage through one of the native Cloud Storage SDKs, which run with administrative permissions and are typically only run on app servers or otherwise trusted environments.

Firebase Storage Security Rule : Check if another object exists / check object's metadata

In Firebase storage security rules (not realtime database), is there any way to perform a check if another object exists at path, or another object's metadata exists?
Some background
Currently my storage security rules are set up so that users only have read access, and not write access to their /users/{userId}/ paths.
I have an admin cloud function that saves a file to /users/{userId}/necessary-file.pdf. And I don't want users to be able to modify or write this file and only cloud functions to have the right to do. To achieve this I think I can match for the filename like :
match /users/{userId}/{fileName} {
allow write: if !fileName.matches("necessary-file.pdf")
}
Question
Is there any way for me to only allow users to write some-other-file.pdf if they already have a necessary-file.pdf at the same path (or even somewhere else if that works better). All while still disallowing them to write necessary-file.pdf.
So is there any way for me to do something like this pseudo-code? :
match /users/{userId}/{fileName} {
allow read: if request.auth.uid == userId;
allow write: if (!fileName.matches("necessary-file.pdf")) && ("necessary-file.pdf".exists())
}
As an alternative, I can have my cloud functions write a metadata to necessary-file.pdf and check for that too. is there any way I can perform something like this pseudo-code? :
allow write: if "necessary-file.pdf".metadata['canUserWrite'] == 'yesUserCan'
Finally
What's really cool about this is that, if this is in any way remotely possible, it can be used to communicate between firebase database and firebase storage rules in a not-so-realtime way. (referring to this question here) A cloud function can listen for changes in the intended field in realtime database, and write a file to firebase storage, which firebase storage can check for.
Firebase's Cloud Storage security rules can only access information about the current request and file. They don't have access to the full storage system, so can't check whether another file is present.
The reason for this is that the rules are evaluated in memory for every request. Providing access to Cloud Storage for other objects would slow the performance down, making the system unscalable. That same reason explains why you can't access the Firebase Database from the security rules.
If you want some control like this, you'll want to look in Cloud Functions for Firebase. If you have your users upload their files into a "staging" area, you can have a Cloud Function validate whether they met all prerequisites and only then move the file into the actual location (making it available for further processing or for clients to see).
(Another Solution) Restricting Storage Access with Auth Claims
Cloud Storage Rules has access to auth info for the request user. By setting up a check during the authorization process an auth property can be added for later access validation in storage rules.
Original Question:
Is there any way for me to only allow users to write
some-other-file.pdf if they already have a necessary-file.pdf at the
same path (or even somewhere else if that works better). All while
still disallowing them to write necessary-file.pdf.
Yes, this could be done by checking an auth.token.
Example flow for a Web App w/ Google Signin:
Create a Cloud Function to set a custom claim that checks for the existence of that file against the current auth user.
Upon success of the user authorizing via Google call that cloud function for it to set a value to the auth object.
Check auth.token in the storage rule.
Web Example for Custom Claims:
https://firebase.google.com/docs/auth/admin/custom-claims?hl=ro#examples_and_use_cases
Example Storage Rule:
https://firebase.google.com/docs/storage/security/rules-conditions?hl=ro#group_private

Resources