Restricting read/write to firestore based on android package name - firebase

I have a Firebase project which contains 3 different android applications. These 3 applications utilize the same data stored under Cloud Firestore. My problem is that some of the data is particular to a single app only while some documents contain data which is supposed to be read by two of the three apps. I need to write Firestore security rules to implement this.
Is it possible to restrict read/writes to a particular document based on the android package name without having to explicitly send data regarding the app-id in each request?
Is there anything else which can be used instead of the package name to uniquely identify the applications while adding firestore security rules?
So far I have been trying to restrict read and writes based on the kind of authentication used by the apps as one app uses only phone auth while the other uses both email and phone linked together. So if the email is missing but the phone is present, I know it's from the first app. Is there any better way to do it?

It's not possible exactly as you're describing. Security rules don't have any way of determining or limiting the origin of access. They just limit who can read and write what data, as determined by Firebase Authentication.
You can use the authentication provider of the signed-in user via request.auth.firebase.sign_in_provider, or any of the other per-user properties shown in the linked documentation. You can also use custom claims in request.auth.token to tag users with some privilege that allows their access to some data, which must be set using the Firebase Admin SDK on your backend.

Related

How firebase Admin SDK differs from firebase console web page?

I'm developing an android app with firebase as a backend and I heard a word named Admin SDK. I had searched for it and found it is used to manage data.
But I have a doubt that firebase provides a console webpage (console.firebase.google.com) to manage data, but why there is a separate Admin SDK?
Can someOne please explain...
The firebase admin SDK provides a simple and easy way to modify firebase settings and data using API calls.
For example, you might ask: why should you even have a regular SDK to store data? After all, you can store and save data directly from the web interface. It is, however, simply not secure or practical to have users update their own data each time using the console.
Similarly, the admin SDK is just like the regular SDK but with administrator permissions. For example, it allows you to bypass the rules set up using your firestore rules. The Firebase admin SDK is meant to be used on your backend - so you know it is running trusted software. You know that it will act the way you expect it to, unlike code running client-side that can't be trusted.
For example, let's say that you want to be able to delete a user's post if certain conditions are met. The user will make the request to your server, and it will check if the conditions are met, and then delete the post using its admin privilages. Sure you could technically automate this using firestorm rules, but those can be quite cumbersome and might not work in more complicated examples.
You can also even use it to integrate with other applications like connecting your app to a moderation tool or a curse detector that can't or shouldn't run on the client's device.
Is your question is why does Admin SDK exists?
There are several administrative tasks such as deleting users, listing collections and many more which the client cannot and should not be able to do.
Firebase Admin SDK has admin access to your Firebase project's resources.
It does not obey any security rules and can read/write any of your database, storage bucket..
That is why you must use Admin SDK in a server (or cloud function only). Although I feel Firebase Admin SDK is more useful if you use your own servers and authentication method. If you are using a custom server then:
It can be used to generate custom token so you can authenticate users using your own method (maybe legacy auth system) but still use Firebase Authentication to handle the auth tokens thereafter.
If you use your own database (and not any from Firebase), the Admin SDK can verify the ID Token sent by client and get identity of that user. Thereafter it's could be a simple if-else statement for you to decide if the user has access to the request resource or not.

safe security rules for cloud firestore (firebase) without user authentication

I need to write safe security rules for a flutter project that doesn't require user authentication (for a reason) for creating new documents.
For all other actions you need to be authenticated.
People are only allowed to create a document if they use the app too.
Is it sufficient if I just limit the amount of created documents in a specific time (with timestamps) and also limit the size, or do I still need to consider something else?
I'm new to firebase but I kind of know that there are ways to do firebase-actions without the app (that will be creatable from the project) via commands if you just get the project-id.
For example that would be a case which I haven't considered yet.
Regarding the last point:
There are three Api keys in the google cloud platform firebase project:
An Android key, an IOS key and a browser key. (auto created by Firebase)
I thought, maybe if I'd apply a restriction to the Android key, so that only Android apps can use it and likewise for the IOS key, the problem could be solved, but I'm not sure.
(I then would restrict the keys via the Google Cloud Platform Project of the Firebase Project.)
People are only allowed to create a document if they use the app too.
This requirement is not enforceable on Firebase. Anyone can take the configuration data from your app, and use that to call the same APIs in the same way. As long as the calls meet your security rules, they will be allowed. And since there's no security rule clause that says "only from my app", you can't limit access to only people using your app.
Is it sufficient if I just limit the amount of created documents in a specific time (with timestamps) and also limit the size, or do I still need to consider something else?
How do you want to limit the document creation in time? If you want to do this per user, you'll need to know the user.
I recommend looking into Firebase's anonymous authentication, which gives user's of your app an ID without requiring them to enter credentials.

Pass context value into firestore document add/set/update from Admin SDK

I am looking to use the https.onCall to accept some input from a user (such as data about another user). I'd then like to do some advanced processing on that data including retrieving sensitive data from other entries on my firestore that should not be exposed. Depending on the outcome of that analysis, I will update other locations in the database. However, I am concerned about the security of the original call and its source. I know that I have the context parameter on the onCall to verify the source was logged in, but I'd like to apply security rules to the final write based on the context.auth provided to the cloud function.
The security rules are straight forward for normal database operations but not if I'm doing an operation (seeded by a normal user) routed through the Admin SDK.
Thoughts?
but I'd like to apply security rules to the final write based on the context.auth provided to the cloud function
As you are aware that you can identify which user made a call to functions as well as that Admin SDK has super-access to database, the general flow should be to write functions in a way that they only edit documents that should be editable by the user.
If you had still like to narrow down access, you can do that for firebase database by passing databaseAuthVariableOverride when initializing admin app.
Read more on authenticating with limited privileges
When you use the admin SDK, or any of the server SDKs, it always bypasses all security rules. Rules only apply to access coming directly from web and mobile clients using the client SDKs.
If you need to apply some sort or restricts to data written from your backend, you will need to code that into the logic of your backend code. Security rules will be of no help.

Hashing algorithm support in firebase real-time database security rules

I would like to compute hash functions inside security rules.
md5hash(auth.token.email) === $hashedvalue
Is there a way for me to do that in bolt? or natively in firebase real-time database?
Use Case:
Basically I would like to store the email as the key in the firebase real-time database and use it in the firebase security rules for authentication and authorization. Since few special characters like dots (.) are not supported in keys I was thinking of using some hashing algorithm which is available in firebase real-time database.
auth.id doesn't work in my case as I'm not giving any sign up option as I have a pre defined set of users with pre-defined profile details accessing my application through their Google login (which I know the email ID of) to start with and since they haven't yet logged into my application I don't have a corresponding ID to authenticate or authorize them on their first attempt.
This page of documentation shows all the functions available in Realtime Database security rules. There are no hashing functions there. You could file a feature request to explain you use case.
For the sake of posterity, I got this working with a small workaround (Yay!).
From the fire firebase real-time database documentation I found out that firebase security rules supports an amazing string function called "replace" xD.
So now I pre process the email Ids by replacing all the characters not supported as database key with their url encoding equivalent before creating the key and use the same set of replacements in my firebase security rules.

Can somebody get Firebase credentials from my apk and use them?

Can somebody else get the Firebase credentials from my APK and use them? Is this prevented by adding the SHA-1 keys for Android?
If it is prevented, what do I need security rules for since only code from my app with my SHA-1 can manipulate database at all?
If it is not prevented, can somebody else use my Firebase database as long as his requests fit the security rules? (Write 2nd client, which actually cannot do bad things but should not be allowed at all.)
Im not sure how I should think about security rules:
A) Protecting data against access and manipulation from bad guys + B?
B) Just a set of rules to keep data in a certain state and prevent my software from doing invalid database request?
A Firebase Database can be accessed via the REST API, or any of the client libraries. The decision about whether a client can or can't do something is entirely based on the rules.
You can even just access the Database URL in a web browser and see a JSON response by putting .json on the end, e.g. https://[YOUR_PROJECT_ID].firebaseio.com/.json
So the answer is definitely B! The default rules in a new Firebase project are that read and write to the database require auth, but you can configure them to provide whatever levels of protection you need.
Take a look at the Database Rules quickstart to see what you can do!
We don't ship the Realtime Database secret (or any other "secret" material) in the json file that gets baked into your app. That file simply contains resource identifiers that allow us to know which resources (database, storage bucket, analytics, etc.) to properly authenticate to (we use Firebase Authentication for these purposes), and we handle server side authorization to ensure that users are properly logged in.
If you are authorizing your requests properly (using Firebase Realtime Database Rules, for instance), your data is secure!
I'd recommend watching The Key to Firebase Security, one of our I/O talks, which talks in greater detail about how this works.
firebaser here
Thanks to the new feature called Firebase App Check, it is now actually possible to limit calls to your Realtime Database to only those coming from iOS, Android and Web apps that are registered in your Firebase project.
You'll typically want to combine this with the user authentication based security that Mike and Ian describe in their answers, so that you have another shield against abusive users that do use your app.

Resources