Several questions have asked to run the firebase-admin package in the browser, such as
Can I break the rules and use firebase-admin on the client side? Or will trying to workaround errors be for nothing?
How to properly use Firebase Admin SDK using Node.js for a web-app?
Error importing firebase-admin
https://groups.google.com/g/firebase-talk/c/Jfq054TLEFQ?pli=1
However, both the questions and the answers given do not properly distinguish between the "browser vs. server/backend" distinction and the "end-user vs. privileged" distinction. A common theme seems to be warning against opening up firebase-admin for end-users, which is obviously a security risk, but they do not explain why a privileged user cannot access privileged Firebase functionality from code running in the browser, only from a backend / server.
So, assuming that a user has sufficient privileges (say, firebase project owner) and is willing to perform whatever authentication needed to transfer these privileges to code running in the browser -- what reasons are there for not doing this? Will it not work? Are there security risks? Is it simply discouraged because a significant fraction of developers will make mistakes WRT the exact requirements for making this work securely?
I think you have a misunderstanding about what a "privileged user" is, as you say.
firebase-admin is initialized with a service account. This is not the same as an Firebase Auth user account. Service accounts are entities belonging to a cloud project that are granted privileged access to some resources in that project. This is how fireabse-admin operates - you init with a service account and gain that privileged access. firebase-admin does not init with a user account.
You never want to expose a service account credentials to a web browser. That's a huge security risk. Since firebase-admin requires a service account, you will never want to use firebase-admin in the browser where it will be seen as public information.
The whole point of the documentation on the matter is to get you to write code to send Firebase Auth user tokens to your backend, where you can safely validate them and decide if that end user should be able to perform privileged operations using firebase-admin. There is really no safe workaround to this scheme - this is the pattern you should follow.
Related
Disclaimer: I am new to mobile app development and have little to no knowledge on authentication systems
Normally, when my mobile app makes https calls to my backend server, I know that I cannot trust that these calls to my server came from my app, as anyone can make https requests to my backend server. Even if I give the app a secret key, it is still possible for a hacker to obtain the key and include it in https requests. Therefore, I will not allow https requests to accomplish whatever it wants on the server; rather, I will limit the request to doing only what a user can normally do with their own data – delete their OWN posts, edit their OWN profile, and so on.
Does Firebase work the same way? I saw this StackOverflow thread regarding OAuth consumer secrets, and how they can be compromised and used to imitate a mobile app.
Is this also the case for Firebase?
Can a malicious user theoretically obtain whatever keys/secrets Firebase gave to my mobile app, and use that to emulate requests from my app to Firebase? For example, could they create new users and cause de-syncing issues with my own backend database?
If so, how can I prevent it?
Thanks.
Does Firebase work the same way?
Firebase works in whatever way you program it. Normally you do not put private keys in software that you distribute to end users. The recommended approach is documented very well - use Firebase Auth ID tokens to indicate who is making the call, and use code on your backend to figure out if they should be able to do the work they are requesting. This is what happens with direct database access from your app, but you have to write security rules to protect data according to your requirements.
If you are passing tokens yourself to your own backend, it is up to you to revoke any refresh tokens that you find to be compromised. You cannot fully stop hackers from compromising a system that stores user tokens on devices that you don't control. All you can do is make it hard for them to do so.
Can a malicious user theoretically obtain whatever keys/secrets Firebase gave to my mobile app
Yes, that's why you don't put secrets in code that you distribute to end users. The Firebase config that you're asked to add to your app is not considered private.
See also:
Is it safe to expose Firebase apiKey to the public?
I want to let my customers send push notifications to their users. I am using Firebase Admin SDK for that, which requires the "service-account.json" file. For security reasons this file should not be shared with others. How could I make this feature available to my customers, without sharing any "secret" information?
If you want to allow your users to send push notifications, you'll have to make a custom API endpoint that you can call from the application they use. It's quite common to use Cloud Functions or Cloud Run for this, but any trusted environment you may already have can work too.
By running the code that sends the message in an environment only you can access, allows you to securely use the Admin SDK that has full administrative access to your Firebase project.
Then when this code gets a request from a user running your app, it needs to check whether this user is authorized to send this message to the user(s) they are trying to send this to. Exactly how to check authorization depends on your app, but some things to consider:
Is any user allowed to send a message to any other user, or is there some mechanism where they opt-in to receiving messages from each other?
Can any message be sent, or is there some mechanism that validates the messages, for example by detecting whether any foul language is used?
These are just some examples of the types of checks you might want to do, and the actual list completely depends on your app and its use-cases.
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.
As I understand firebase security rules are for authenticating different types of users and provide authorization based on that, but what if my application doesn't need users to register at all? What if I just need to authenticate the application, not the users? What I mean by that is, I need to assure that particular firebase products are only accessed through an given application.
What I currently do to achieve that is, just make the security rules public assuming that the specific firebase sdk does the authentication stuff, but when I do that, I get the weird warning from the firebase console that security rules shouldn't be public. What am I doing wrong?
Another question, shouldn't we authenticate any application trying to access the firebase products even before starting the user authentication?
I also would like to learn how this is done generally (best practices) when developing serverless applications with firebase/google cloud platform products.
Firebase security rules don't support authenticating apps, only users. Authentication of an app would be pretty easy to simulate by an attacker, as all you would need is the secret compiled into the app in order to fool the rule. Even if you obfuscate the secret data, it's still just public data, and someone will figure out how to use it.
Once you ship an app to the world, you should consider everything in it to be public information, no matter how hard you might think it would be to extract that information (it's not that hard, really).
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.