I've read the docs about Firebase Auth Limits in https://firebase.google.com/docs/auth/limits. It states that there is a limit of 1000 requests/second per project. There is no example or any explanation about what those API Limits are. What kind of actions are counted in the API Limit? Does verifyIdToken() and createUser() in Admin SDK count as an API Request?
I am also aware that there is a duplicate question here but it hasn't been answered well.
I've asked Firebase Support about the API Limits and got the following response:
The API’s quota applies depending on the Firebase API you want to
use. In this case the API quota applies to the use of the Firebase Auth REST API. Using it, you can query the Firebase Auth backend
through a REST API. Also, it can be used for various operations such
as creating new users, signing in existing ones and editing or
deleting these users.
To create, and refresh a token the quota will apply, if you use the
REST API to do the operations. However, even if you don’t use the REST
API there are other internal quotas associated with the refreshing of
the token. In order to avoid refreshing the token so many times, set
forceRefresh to false to minimize unneeded token refreshes when a
valid token may still be cached.
I've also asked about the internal quota when refreshing the token using the official sdk and got this reponse:
Unfortunately, some quotas are internal, and confidential information.
For this reason, I am not able to share it with you. However, if you
receive quota errors you can contact us
The rate limit includes both the Client and Admin SDK:
The API limits encapsulates every request that comes from the API.
This includes various operations such as creating new users, signing
in existing ones, and editing or deleting users. The limits apply to
requests coming from both the Client and Admin SDK. This means that
Firebase allows you to have 1000 simultaneous requests/second (both
from Client and Admin SDK) in a project.
~ Firebase Support
Related
Firebase Auth provides a REST API to create/delete/edit auth users. As API Keys are not private, anybody can use the API.
The endpoint e.g. to create new users is publicly available and can't AFAIK not be disabled.
This is in my opinion a bad situation as e.g. an attacker could create via this endpoint lots of users which are no valid users for our system. An attacker could block valid email addresses of customers which are then not able to create their valid accounts.
If an attacker knows a userID he could even delete auth users.
We added user claims (which can only be set via the Admin API and not via the public API) to ensure only users created by us are allowed to access our systems but it would mean a lot of effort on our side to regularily delete users not created via our system.
Is it planned to protect FirebaseAuth also via AppCheck to allow only verified apps to access the auth api?
At this point, I would say it's unlikely as this type of abuse is considered a low risk in comparison to the APIs that app check is protecting.
The public-facing Firebase Auth APIs are rate-limited and the web APIs in particular must come from your permitted auth domains. However, one of the platform's key selling points is the ability to handle many concurrent users.
100 accounts/IP address/hour can be created
10 accounts/second can be deleted
Can handle 1000 requests/second, 10 million requests/day for public APIs across a project
The per-IP address limits are bypassed by using the Admin SDKs (subject to a 500 requests/second limit). You can also boost these limits temporarily from the Firebase Console if you are expecting a spike in demand (e.g. you offer a Black Friday sale).
Only the Firebase Auth API for creating users is "exposed", but limited as detailed above.
Editing, deleting, updating a user's details both metadata and the account itself are privileged actions - you must be appropriately authenticated to make changes. In the case of a user account connecting from a client device, you must have signed in within about 5 minutes to be able update/delete your own account. When using an Admin SDK, the requests are authenticated with a service account's credentials which authorizes it to make changes on behalf of users or the system.
If your system were to abused in such a fashion, reaching out to Firebase Support would be your point of call.
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.
I am building an app, where I need to use my own backend besides Firebase. I need to authenticate a logged-in user in my backend too. So I found this tutorial which does this. I send an idToken and verify this header in admin sdk in my node, based on the docs. I thought I could cache this token with redis or just a js map after the first verification for 10 minutes or as much as a user session would take, to speed things up, instead of verifying each request in a 10 min sess. I could probably cache the token in the phone too for some time?
My question is, what security consequences would this bring? Thank you.
To clarify I am not using custom tokens, I will be using the built in Firebase Authentication.
The convention is to send the ID token to your backend with every request. It's not expensive to verify the token with the Admin SDK as shown in that documentation. It doesn't cost any money.
Typically what you're supposed to do is use a listener to detect when the ID token changes (it will be refreshed automatically every hour), and keep using that token until the SDK delivers a new one to your callback. In web clients, you're supposed to use onIdTokenChanged to register a callback to get changes to this token over time. There is no need to persist or cache this token - simply use whatever the callback most recently provided.
Some of the Firebase backend services keep a small cache of recent ID tokens, and their decoded results. So if they receive the exact same token, they'll use the already decoded result. This is a riskless operation, as the decoding operation is idempotent: the same input will always deliver the same output.
I have to build an API using Firebase, and need some help with design choices. I want to be able to sell the API to users, who can then use it to build/integrate their own applications. Users will have both read and write privileges.
General information:
I'm using Firestore db with email & password authentication.
Only specifically assigned users may use the API
Each user may only access specific documents concerning them.
I've noticed 3 different ways in which an API can be provided to a user of my Firestore db:
https triggered cloud functions (https://firebase.google.com/docs/functions/http-events)
Using the SDK (https://firebase.google.com/docs/firestore/client/libraries)
Using the REST API provided by Firbase (https://firebase.google.com/docs/firestore/use-rest-api)
API requirements:
Used only by users that I specifically grant access to (email & password login)
I want to limit these users to only a couple of read/write tasks that they're able to perform.
It needs to be safe.
My current approach is:
Use the 3rd option - the REST API provided by Firebase (thereby giving users the projectId and API key)
Add authorised users to the list of authorised accounts on Firbase, and limit access using custom claims and database rules.
My questions:
It seems that https functions (option 1) are normally used in API building. Are options 2 and 3 unsafe?
What are the normal use cases of the 3 options? When should each be used and when should each be avoided?
Are there any obvious flaws in my choice of option 3?
Any other useful information about making these design decisions will be much appreciated.
Thank you in advance
TL;DL: It depends on what you want to do with this API and how many and what type of devices/users will be calling it.
Before answering your questions I will list below the advantages of each approach:
Cloud Functions:
Cloud Function is a Functions as a Service Solution, so it's also a hosting service for your API, therefore you won't have to provision, manage, or upgrade servers and the API will automatically scale based on the load. Also this option takes into account the pros of SDKs and client libraries, since your code will have to use it to connect to Firestore anyway.
SDKs and client libraries:
This is the easiest and more optimized way to reach Firestore, however, environments where running a native library is not possible such as IOT devices will be left out of your solution, so consider this while implementing this option.
Cloud Firestore REST API:
Every device properly authorized to access Firestore will be able to do so.
NOTE: For both SDK and REST API you will need to consider hosting of your API, either on Cloud Functions, as mentioned, App Engine Standard, App Engine Flex or a Compute Engine Server Instance.
All that being said, it's up to you and your API's usage and requirements to say which option is best considering the points above.
As per security, I'd say that all option can be secure if firebase rules and firebase auth are set correctly.
The firebase auth doc shows that you can only make Firebase Auth API calls up to 500 requests/second per service account & 1000 requests/second per project.
e.g. If I use Firebase Auth Admin SDK to invoke getUserByEmail or updateUser, do these operations count toward API limits?
How about verifying id tokens using verifyIdToken API? If my project verifies all requests coming in to the server from clients by verifying authIdToken, does that mean that my server's upper scaling threshold will be 1000 requests/second per project because the server's one of downstream services, Firebase Auth, can only accept up to 1000 requests/second to verify auth id tokens?
Firebase doc seems to be lacking details related to these API limits.
Yes, 1k/s includes all limits from the Admin API. I feel if the downstream can only handle 1k/s you can always implement a backoff or throttle algorithm to handle higher burst load at times. I assume these are mostly sufficient for user auth as user don't login frequently. For machine to machine, I suggest you use a different auth system.