Is it possible to protect firebase http triggered functions without auth and accept calls only from my firebase hosted app?
I want my web app to call firebase functions with unauthenticated users but I don't want this functions to be accessible from anywhere else.
This is not possible to enforce. All of your HTTP functions are accessible by all other clients out there, regardless of where they are in the world (unless something in their network is blocking them).
You could certainly make an attempt to guess if a request did not originate from your web site (by looking at the referrer header), but that information can be easily spoofed by an attacker.
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'm working on a web app running on firebase services. I've created an express back-end running on Firebase Cloud Functions and hosted on Firebase Hosting. I am trying to add authentication so only users with permissions can access admin pages.
I tried implementing session cookies as described here. It was successful but unfortunately was vulnerable to CSRF attacks since Cloud Functions strips all cookies without the name __session from incoming requests so the proposed csrfToken cookie solution is impossible.
I then considered using Auth's persistence in the client's local storage and sending the token in the header of a GET request. Unfortunately, I have only found tutorials on how to do this for requests within scripts e.g. for APIs, not for GET requests directly from the browser to serve a page.
It seems that there should be a simple solution. Am I missing something? Is cloud functions not meant for serving web apps like this? Is there another way to protect against CSRF without cookies? If Cloud Functions still allows the __session cookie is it meant to be used for storing the user's Auth Token and if so does it protect against CSRF anyway?
Thanks
In the firebase Cloud Function you can implement your own Auth. However Firebase provided its own Authentication method. In the Cloud Function, it is simple use the ‘functions.auth.user().onCreate() ‘ method. You can refer to Extend Firebase Authentication with Cloud Functions documentation for samples.
As for your GET question, are you asking about how to programmatically extract the parameter from the URL? It'ss similar to this; you can pull the URL and substring the part that contain the token.
I have a simple web site hosted in Firebase and it is making AJAX calls to REST API endpoints in GCP Cloud Run.
I would like to limit these endpoints only to the calls coming from this site hosted in Firebase. Any call coming from any other origin should not be able to use the endpoints. What is the best way to do this?
When I was not using GCP Cloud Run, I was doing a host check on the API side to make sure that request is coming from my client but now with Cloud Run this is not possible. What else could be done?
Please note that the web-site hosted in Firebase is very simple and do not do any user authentication.
Challenge: Restrict access to a Cloud Run service to a single web application, without relying on:
Restricting access to the web application
Imposing authentication on users
This difficulty is not specific to Cloud Run. It's a general challenge for static sites backed by APIs, and a reason why many sites have authentication. As mentioned in the question comments, a server-side "host" check is not a meaningful security layer, as everything in the HTTP request can be faked. I strongly recommend you not worry about keeping your API private or add user authentication to keep the system simple and access accountable.
If that's not possible, you can still take the authentication approach by creating a single user, embedding the credentials in the site, and rotating them regularly (by redeploy to Firebase Hosting) to prevent credential theft from having indefinite access to your API. Having Firebase Auth in the middle is better than a simple API key because it prevents replay attacks from accessing your API.
I'm building a React+Redux app, and using some firebase cloud functions which I call in an action creator. I was wondering, if I should save the cloud function url as an environment variable, since this code is on the client side? I already have cors implemented to only allow requestsfrom my domain.
Thank you
In general, you should always make sure that endpoints that can be called from a client are robust enough to be secure if publicly disclosed. Browser, Android, and iOS apps can all be inspected and disassembled to discover outgoing request URLs.
"Security through obscurity" can buy you time, but is not in and of itself a real means of protecting your application. Instead, you should make sure that the endpoint requires sufficient authorization (e.g. by using the Firebase ID token as per this sample).
In other words, there's no need to hide it because at the end of the day, you can't!
I know that we can use a Firebase backend function to send an HTTP request to Google Apps Script and receive it using "doGet()".
However, is it possible to call a Google Apps Script function from Firebase without sending an HTTP request (since it's part of the same Google account)?
My concern is with security, where one may be able to guess/sniff the right URL/parameters and then execute the Google Apps Script function (which makes a purchase). Alternatively, there may be a proper way to secure GAS web apps.
There are quite some details missing. But I think you're asking of a Google Cloud Functions/Cloud Functions for Firebase can call into an Apps Script web app or a Apps Script REST API. The answer is that they indeed can invoke those URLs (if they're publicly accessible and fall within your quota).
But that is no more security risk than that any browser can invoke these URLs. The security should not come from knowing or being able to call the URLs. If you want to secure an API, you should implement proper security on it. For more on see Authorization for Google Services in Apps SCript