Why can't we connect to firestore on node.js server using just public apiKey - firebase

In my React project, I am using firebase public apiKeys to access services like authentication and firestore. So it means we are not required to use admin-sdk.
Then why we need admin-sdk to leverage firebase services on server environments like node.js? Won't public apiKeys do just fine?
I mean client side is exposed to public while servers can be accessed by only the managers and developers of the organization.
Please explain me the reason for this.
Thank You!

The client-side SDK's can access resources like Firestore, Storage, etc, but the requests to these services need to pass the Security Rules.
The Admin SDK bypasses the security rules - and hence the Admin SDK needs to be run in a secure environment.
To answer your specific query though - you can use the Javascript Client SDK on a Node.js environment - but you have to keep in mind that the requests will be subject to the security rules you define for your Firebase resources. If you use the Admin SDK, your requests will bypass the security rules.

Related

Using Firebase Security Rules from a web server

Do any of the Firebase Node/JS SDKs support making calls to Firestore from a node server or cloud functions (e.g. nextjs, remix) on a users behalf, respecting security rules for the authenticated user and supporting sessions for multiple simultaneous users?
Use case:
I have a mobile application with Firebase Security rules set up. I want to serve the same data from a server side web application without reimplementing the Firebase security rules on the web server and keeping them in sync.
e.g. if a user requests a post by id, and Firebase rules prevents them from having access to that specific post, I want Firebase to tell me that and for the web server to forward the 403 status to the user.
More info:
I read this:
If you are developing a Web or Node.js application that accesses Cloud Firestore on behalf of end users, use the firebase Client SDK.
Which suggests this should be possible, however my understanding is that:
firebase-js-sdk can only have one user authenticated at a time so would not be safe if handling async calls from multiple users at once
firebase-admin can be run as a specific user, but this can only be done during initializeAdminApp and again would affect all requests that are currently using the firebase-admin import
Is that correct? Are there any other ways to act on behalf of the authenticated user from a web app?
The only thing I can think of would be the REST APIā€¦
https://firebase.google.com/docs/firestore/use-rest-api
Do any of the Firebase Node/JS SDKs support making calls to Firestore from a node server or cloud functions (e.g. nextjs, remix) on a users behalf, respecting security rules for the authenticated user and supporting sessions for multiple simultaneous users?
No, the backend SDKs always bypass security rules. Only the web and mobile SDKs that you use inside the client app make use of authentication tokens available from the user's prior sign-in.
You could consider using the REST API instead since it allows you to pass through a client auth token. It will be up to you to manage the transfer of that token manually.

firestore security rules for server side requests

i'm flutter-fire user since last fall
Note: The server client libraries bypass all Cloud Firestore Security
Rules and instead authenticate through Google Application Default
Credentials. If you are using the server client libraries or the REST
or RPC APIs, make sure to set up Identity and Access Management (IAM)
for Cloud Firestore.
Comment above is from link by firebase team. It sounds like 'server client libraries' or apis in the comment mean the requests from outside of my mobile apps, and they gon bypassing cloud firestore security rules. But when i tried the same get request with Postman with just same request from the one in my app without permission, the response in Postman console was fine, which means that there came a permission denied error.
So, here comes my question. I hope to know what types of requests exactly are equivalent to these 'server client libraries' or 'the REST or RPC APIs' mentioned in the official reference that bypass all the security rules. Postman is exactly 'the REST', and firebase worked as i wanted(produced permission denial) perfectly in this case. So there must be some specific types that firebase team actually intended to refer to be careful of.
I understand that firebase-admin sdk is one of the possible server side libraries, but exactly the same permission or auth procedures should be required when we tried to access firebase admin sdk which can control firebase data above the security rules just like firebase team commented. So the question is focusing on possible attackers' solutions to maliciously manipulate our firebase without the proper security procedures.
Hope some firebase gurus would give cool answers for the question with awesome knowledge and experiences! Thank you in advance [:
As their name indicate, the server client libraries are to be used from a server or from a "trusted environment" like Cloud Functions.
When interacting from your server (or your trusted environment) with the Firebase server APIs you don't authenticate as you would authenticate from a client application. Instead of using user accounts created through the Firebase Authentication service (e.g. email/password account) your server should use Google service accounts. More details here in the Firebase doc.
Note that for Cloud Functions, you initialize the Admin SDK with no parameters. In this case, the SDK uses Google Application Default Credentials (exactly as indicated in the documentation excerpt you mentioned in your question).
So, when your server (or your Cloud Function) interacts with the Firebase server APIs, since it is authenticated with a service account, the requests bypass all Cloud Firestore Security Rules. In other words, if you want to implement some check to allow/forbid specific operations based on specific parameters/values, you have to implement them in your code.
For the REST API, it is the same. The REST API can be used from a client application (a web app, a Flutter app, ...) or from a server.
Depending if it is a client or a server, you should authenticate by using a Firebase Authentication ID token or a service account (together with Google Identity OAuth 2.0 token), as explained in detail in the documentation.
So, when you make a request to the API with Postman without permission, as you did, the API detects that there is no Google Identity OAuth 2.0 token or Firebase Authentication ID token associated with the request and then the Security Rules are enforced => you get a "permission denied error".
In conclusion, if you correctly define your Security Rules you should not encounter any problem with "attackers maliciously manipulating" your database.
Note however that Security Rules only based on auth != null may not be sufficient to protect your data, as explained in this answer.

hide firebase private credentials in client apps

I would like to avoid exposing private credentials in client apps. Doug Stevenson said firebase-authentication-vs-firebase-admin :
The reason why you can't use the Firebase Admin SDK in your app is
because you would have to ship private credentials with your app in
order for the SDK to operate
By saying Admin SDK did he mean when we use for example:
import * as admin from "firebase-admin";
And what about :
import firebase from "firebase/app";
firebase.database().ref ... ?
Is this snippet considered as admin SDK ? To configure firebase we would still need to ship private credential with our client app, which is a security hole. So should we consider NEVER use firebase.database() or firebase.firestore() in client apps and instead use a cloud function ?
If you ship your administrative credentials with your application, anyone can grab those credentials and start calling any API on your project in whatever way they see fit. You have no control whatsoever over this usage, as they'll have the administrative credentials.
For this reason you should indeed not use the Admin SDK in the app, but instead wrap the functionality you need in a custom API (such as in a Cloud Function), where you can ensure its usage is authorized.
This is different from the second snippet in your question, which uses the regular JavaScript SDKs from Firebase. These SDKs don't use administrative credentials to access the project, but instead use the configuration data that is explained here: Is it safe to expose Firebase apiKey to the public?
Access through this configuration data is guarded by the server-side security rules that you've configured for your project. So while the user can still copy the configuration data and call the API on their own, any access has to go through the security rules you configured. And in those security rules you then ensure they can only access data they're authorized to.
But since the Admin SDKs bypass the security rules by design, you won't have that option when you ship the administrative credentials in your app.

Firebase Hosting doesn't has firewall?

Having one of application hosted on Firebase with some additional services there (Cloud Firestore, Cloud Storage for Firebase, Cloud Functions for Firebase) decided to make some security scanning. One of the tools https://sitecheck.sucuri.net/ shows me that there's no firewall for it, is it possible? It has reverse proxy & Fastly's CDN, but would be a firewall missing for apps hosted on Firebase Hosting?
Firebase hosting resources access is unfortunately not restricted by any means, check out the question below?
Can Firebase restrict access to resources?
However, There are things you can do in the regard of security:
Use Cloud functions to render dynamic resources and microservices
https://firebase.google.com/docs/hosting/functions
Use Firestore rules to secure the data access
Use Firebase authentication to make sure that only authenticated users can do certain actions
Even though, we all hope for that firewall option to be added.
Best Regards
Firebase Hosting does not have a firewall feature. If you publish content to it, that will be accessible from anywhere there is an internet connection.

Firebase security rules, How to authenticate client app, not the users?

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).

Resources