how to make authenticated requests to Firebase Realtime Database with api key - firebase

What I want is to perform rest requests to Firebase Realtime Database from my esp8266 with micropython firmware without complex authorization process.
I know that I can turn off authorization at all in the rules but I'd prefer to have at least some basic security.
Can't I just use my Web API Key for this purpose?
Here is a doc which tells that there are 2 ways of authentication: oauth2 and generating key manually. Second way seems almost what I need but it requires setting up Admin SDK and as far as I understood still requires regenerating the key from time to time.
So eventually I have no answer to a simple question: how to authenticate rest requests to the Firebase Realtime Database in the most simple way?

The same page you linked to contains a section on using legacy tokens (also known as "database secrets" in the past). While those are not recommended anymore, they continue to work and are as simply as adding the (non-dynamic) database secret to your URLs.
I suggest you read the links at the bottom of the documentation. But I do recommend that you switch to using the OAuth or ID Token flows as those are much more secure.

Related

How does Firebase authenticate requests from my app?

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?

Firebase custom auth in server-to-server scenario

I need to implement a scenario where, after a file is uploaded to Google Cloud Storage, a function is triggered and processes the file. In this case, processing basically means sanitizing the file, storing it into Firestore and making it accessible via another HTTP-triggered function (a REST API of sorts).
Both user-facing ends of this process (a file upload and HTTP function) need to be secured. The process will be used in server-to-server scenario: one side is going to be a backend written in either Node.js or .NET, the other will be my Firebase solution (Cloud Storage and HTTP-triggered function as per above). In Firebase, I am going to maintain a custom set of users that should have access to the system - my idea was to use a simple system where each user will have a client id and a client secret (basically an oAuth client credentials grant type).
Based on what I read online, an only option to implement this is to use [Firebase auth with custom tokens][1]. I found lots of examples online on how to do that, but it was always about client-to-server scenarios (e.g. a Javascript web app talking to REST API). Server-to-server scenarios were not mentioned anywhere and indeed, I am unsure how to go about implementing it - I can call auth.createCustomToken(uid) just fine in my HTTP Firestore function, but there seem to be no server-side libraries I could use to call auth.SignInWithCustomTokenAsync(customToken).
To sum it up:
How can I use Firebase auth with custom tokens in server-to-server
scenario, where I need to sign in using a previously generated
custom token from a server environment?
If it is not possible,
what's the other alternative to securely implement the
above-described architecture?
I've contacted Google Support and if anyone else is struggling with this, in server-side scenarios, recommended approach is to call signInWithCustomToken endpoint in Firebase Auth REST API.

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.

Is it safe to send the access token in the URL? Firebase Realtime Database REST API

I am using Firebase realtime database rest API on the client-side. I noticed that you need to send the access token on the URL and this info is exposed on the request.
Is this a secure way of using the REST API? Is there another more secure way of accomplishing this?
Here is the documentation: https://firebase.google.com/docs/reference/rest/database#section-param-auth
When you see "https" at the front of the URL used for the API, that means the data is encrypted and can't be intercepted. So passing data along with the query should not pose a security problem in terms of someone gaining access to your key.
However, if you ship a client app that contains the key, you are basically giving it away to anyone who has your app, as it's always possible for someone to reverse engineer your app and gain access to all data inside it. To avoid that, you should be using Firebase Authentication and security rules to determine who can access the data in your database.

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