Firebase AppCheck VS hackers & spammy requests - firebase

Although I fully understand the use of AppCheck, I still wonder how it can help against spamming request to an API endpoint.
In the scenario of a hacker using OpenBullet or whatever hacker tool to spam thousands of requests per minutes to a specific endpoint (for example, a Signup endpoints to create thousands of fake profiles in a social app):
once the hacker got their hand on the appcheck token from the device, can't they simply attach it to the request's header, and spam all they want the api endpoint that we secured from our backend by checking appcheck token?
I mean, as long as the TTL didn't expire, I guess all their requests will pass the check thus they could use their hacker tool and pretend to come from the untempered app? Or am I missing something?
I guess a solution would be to:
1- forceRefresh the appcheck token on each fetch request from the mobile app
2- expire the received appcheck token programmatically after successful verification from the backend, so that further request would need a new one that can only be generated from the app, thus making it harder for the hacker?
Any help is appreciated! :)

I'll put it in a different way. While AppCheck offers a level of protection to your resources, it does not guarantee 100% protection. The sample you gave is an instance on how it could be bypassed. But what can't be factored out is that AppCheck makes it harder for a malicious actor to roam around your services and consume them on your budget.
Take a look at this section from the documentation. Also take a look at this question as it was asked after your question and had a firebaser (Frank) corresponding to it.

Related

Firebase authentication vulnerability. Unknown users in firebase

So I have an app where I have enabled google authentication in my firebase project. 25 people I know were authenticated. When I logged in the backend I saw atleast some 80 entries with some weird sounding email addresses which should not be there. I had to delete all the entries manually, known and unknown ones (didn't needed any after sucessful testing). Now that I want to go live, I am really concerned as to how unknown entires entered my firebase authentication records?
This has recently happened 'again' to another new app/project of mine. This time I disabled that unknown email address and took a screenshot (attached).
I really really need to know and understand how safe is data on firestore. If someone can manage to 'hack' the Authentication part and add thir email to Authenticated list of users they may also be able to penetrate the database somehow in future. Please help me in understanding what is happening?
While researching on this, I could only find this similar question but the answer was just not enough explanation for me.
Unknown user in my firebase user authentication (Flutter/firebase)
firebaser here
Since the configuration data for your project is embedded in the application that you send to your users, any user can take that configuration data and then start calling the API with it. This is not a security risk, as long as you secure access to the data within your project correctly for your requirements.
See Is it safe to expose Firebase apiKey to the public?
What it means to correctly secure access to your data is hard to answer, as it depends completely on your use-case.
For example: the content-owner only access security rules allow a user to enter data in the database, and then they can access the data they entered. With these rules there's no risk if anyone uses the API (and not your app) to do the same. The security rules will ensure they only can access data they're authorized for, no matter what the source is the API calls is.
It may be related to the pre-launch report.
https://support.google.com/googleplay/android-developer/answer/9842757?visit_id=637478112313064713-650300184&rd=1#signin
Step 1: Provide test account credentials if your app has a sign-in screen
If your app has a sign-in screen and you want the crawler to test the sign-in process or the content behind it, you need to provide account credentials. Note: You do not need to provide credentials if your app supports 'Sign in with Google', which enables the crawler to log in automatically.
So I guess it is safe.
The user willwhiteapple#gmail.com is the apple testing when your application is in the process of validation from apple before deploy to TestFlight .

How to reliably stop receiving notifications when user logs out

I have a server, and multiple clients (web & mobile). When my users log in, I want to start sending them notifications about the content they follow. When they log out, I want to stop sending them notifications.
I've found many Stack Overflow questions that are similar to mine, but none have been completely answered.
The closes to my question was this other question where the accepted answer is to call deleteInstanceId() when the user logs out, which seems like the most solid solution, but in the comments someone copy pasted from the (GCM) docs that "Developers should never unregister the client app as a mechanism for logout or for switching between users". I wasn't able to find the same notice in the new Firebase docs, but I assume that it's the same concept: the InstanceId is not supposed to be user related.
The only alternative I've found, is to send a "signOut" request to my server, with the instanceId, and my server needs to remove the associated instanceId from the user account.
But what if that API call doesn't go through? This seems to be quite a fragile solution.
So this is what I would do now:
Send the instanceId to my server when the user authenticates
Make sure that this same instanceId is not used by another user, since this could happen when the other user logged out on the same device, but the API call didn't go through
When sending notifications, send them directly to the registered instanceIds (initially I had planned on using topics, but in combination with handling my tokens, this seems even more fragile).
When the user logs out, send a signOut request to my API, and remove the instanceId from the user.
Your question seems to just be seeking validation for a design, which really isn't the purpose of Stack Overflow. The Firebase subreddit might be a better alternative for drumming up conversation around the problem.
But I will say that if it works for you, then run with it. Consider also sending the target users's UID in each message, and have your app compare that with the currently signed in user in order to determine if it reached its correct destination. Send a message back to the server if it's not in order to correct the problem.

Drive API OAuth2 with HTTPS Only

I have been studying the DriveAPI for a while now and can't seem to find a simple way to get it to work just for MY needs only...
I would like to use the DriveAPI only with just the REST API (HTTPS).
There are many things like token, clientid, apikey, secrets, etc.
All I need, is to search MY OWN GDrive files (FULLTEXT CONTAINS) and get a result from the API but I can't get it to work.
Please remember, this is for my own needs only and I would like to bypass the verification (login) window and get some kind of token, that lasts forever, so I can implement this in my own tool.
So, how can I authenticate and use the DriveAPI with just plain HTTPS?
My efforts so far:
I have already made a client ID and a client KEY for a sample project in the dashboard. I have also an Google Drive API KEY. From this point, I don't really know where and what to send.
As I mentioned in my comment, there is no "bypass" for the OAuth 2.0 authentication (that's why there is authentication enforced in the first place). Have you done any coding for this that you can share? For most REST API's OAuth 2.0 authentication is required. Your application must be able to request the token and use it to make the requests.
Google API's use Google Identity service to provide the tokens. In the following document there are many examples of how this implementation should be done in different programming languages:
https://developers.google.com/identity/protocols/OAuth2WebServer

Firebase cloud function: how to deal with continuous request

When working with Firebase (Firebase cloud function in this case), we have to pay for every byte of bandwidth.
So, i wonder how can we deal with case that someone who somehow find out our endpoint then continuous request intentionally (by a script or tool)?
I did some search on the internet but don't see anything can help.
Except for this one but not really useful.
Since you didn't specify which type of request, I'm going to assume that you mean http(s)-triggers on firebase cloud functions.
There are multiple limiters you can put in place to 'reduce' the bandwidth consumed by the request. I'll write a few that comes to my mind
1) Limit the type of requests
If all you need is GET and say for example you don't need PUT you can start off by returning a 403 for those, before you go any further in your cloud function.
if (req.method === 'PUT') { res.status(403).send('Forbidden!'); }
2) Authenticate if you can
Follow Google's example here and allow only authorized users to use your https endpoints. You can simply achieve this by verifying tokens like this SOF answer to this question.
3) Check for origin
You can try checking for the origin of the request before going any further in your cloud function. If I recall correctly, cloud functions give you full access to the HTTP Request/Response objects so you can set the appropriate CORS headers and respond to pre-flight OPTIONS requests.
Experimental Idea 1
You can hypothetically put your functions behind a load balancer / firewall, and relay-trigger them. It would more or less defeat the purpose of cloud functions' scalable nature, but if a form of DoS is a bigger concern for you than scalability, then you could try creating an app engine relay, put it behind a load balancer / firewall and handle the security at that layer.
Experimental Idea 2
You can try using DNS level attack-prevention solutions to your problem by putting something like cloudflare in between. Use a CNAME, and Cloudflare Page Rules to map URLs to your cloud functions. This could hypothetically absorb the impact. Like this :
*function1.mydomain.com/* -> https://us-central1-etc-etc-etc.cloudfunctions.net/function1/$2
Now if you go to
http://function1.mydomain.com/?something=awesome
you can even pass the URL params to your functions. A tactic which I've read about in this medium article during the summer when I needed something similar.
Finally
In an attempt to make the questions on SOF more linked, and help everyone find answers, here's another question I found that's similar in nature. Linking here so that others can find it as well.
Returning a 403 or empty body on non supported methods will not do much for you. Yes you will have less bandwidth wasted but firebase will still bill you for the request, the attacker could just send millions of requests and you still will lose money.
Also authentication is not a solution to this problem. First of all any auth process (create token, verify/validate token) is costly, and again firebase has thought of this and will bill you based on the time it takes for the function to return a response. You cannot afford to use auth to prevent continuous requests.
Plus, a smart attacker would not just go for a req which returns 403. What stops the attacker from hitting the login endpoint a millions times?? And if he provides correct credentials (which he would do if he was smart) you will waste bandwidth by returning a token each time, also if you are re-generating tokens you would waste time on each request which would further hurt your bill.
The idea here is to block this attacker completely (before going to your api functions).
What I would do is use cloudflare to proxy my endpoints, and in my api I would define a max_req_limit_per_ip and a time_frame, save each request ip on the db and on each req check if the ip did go over the limit for that given time frame, if so you just use cloudflare api to block that ip at the firewall.
Tip:
max_req_limit_per_ip and a time_frame can be custom for different requests.
For example:
an ip can hit a 403 10 times in 1 hour
an ip can hit the login successfully 5 times in 20 minutes
an ip can hit the login unsuccessfully 5 times in 1 hour
There is a solution for this problem where you can verify the https endpoint.
Only users who pass a valid Firebase ID token as a Bearer token in the Authorization header of the HTTP request or in a __session cookie are authorized to use the function.
Checking the ID token is done with an ExpressJs middleware that also passes the decoded ID token in the Express request object.
Check this sample code from firebase.
Putting access-control logic in your function is standard practice for Firebase, BUT the function still has to be invoked to access that logic.
If you don't want your function to fire at all except for authenticated users, you can take advantage of the fact that every Firebase Project is also a Google Cloud Project -- and GCP allows for "private" functions.
You can set project-wide or per-function permissions outside the function(s), so that only authenticated users can cause the function to fire, even if they try to hit the endpoint.
Here's documentation on setting permissions and authenticating users. Note that, as of writing, I believe using this method requires users to use a Google account to authenticate.

Firebase refresh-token expiration

While testing the security of one of our product, a web application, using the REST API of Firebase we got surprised when we realised that refresh-tokens never expire in the V3 of the Firebase implementation, allowing any refresh-token to create new tokens forever.
While local-storage seem a reasonably safe solution today, we are concerned by the possibility that it could fail tomorrow, even for a short amount of time, and that we cannot stop someone from using any of these refresh-tokens.
Two factor authentication will help mitigate the issue, but the first step would become compromised nonetheless.
Is there a way to blacklist tokens, or similar behaviour, with Firebase, without handling all tokens exchange, such as minting, ourselves? We could not find such feature when going through the doc.
Any advice appreciated.
Authentication sessions don't expire with Firebase login. But the ID token will have to be refreshed hourly, to keep access to the services. If you disable an account, refreshing the token will fail and the account won't be able to access services anymore. There is no way to invalidate individual tokens.
Firebase recently implemented revokeRefreshTokens() inside the admin sdk. Although this will not let you kill an invalid JWT, it does allow you to prevent a refresh of the token (from my testing so far at least) and it allows cleaner control flow inside firebase database.
See Admin Manage Sessions For rough examples

Resources