Is it possible to only allow authenticated users to use callable function, without getting billed for invalid invocations? - firebase

I have a callable function that gets users auth data and validates it (inside the function), if user is not authenticated or allowed to do a certain action I throw respective error.
However nothing stops malicious actors to run a loop that constantly pings such function and rack up cost in terms of invocations / little bit of time those functions run.
Cloud providers like AWS have systems in place where this auth check is set up on an api gateway / loadbalancer level and users are not billed if someone calls functions with unexpected headers / payload or without authentication.
Does something like this exist for firebase, perhaps via google cloud?

No, it's not possible. The callable function must execute in order for the firebase-functions SDK to verify the user's ID token via the Firebase Admin SDK. It's not a "free" operation in any way. No matter how you write or deploy it, something is going to have to invoke the Firebase Admin SDK to verify the token - it's not part of any unbilled cloud infrastructure.

Related

Can you use Unity / Firebase Auth with C# google cloud functions?

I'm looking into porting a unity game with a dotnet backend over to firebase firestore / functions, etc. My initial tests look promising, but my biggest hold-up is that I would need to rewrite a lot of the server-side logic in JavaScript.
I know that firebase's functions and firestore both run on google cloud, and the cloud version of functions supports a number of additional languages, including c#. I was able to create a couple of C# test functions and upload them to the same project as my unity test. They show up in the firebase portal and can be called via the HTTP endpoints supplied by google cloud, etc.
I discovered that I can call the function that does not require auth using the FirebaseFunctions callabale API in unity (fun fact, it only seems to work if the response is a JSON object in the form of { "result": [data here] }) I cannot, however, call the version of the same function that does require authentication - it returns an internal error message.
I am wondering there is a way to make these methods callable from the unity firebase API - passing in the user id/auth that I get from logging into firebase? I've seen some examples/answers where people say to call the cloud function directly using the Authorization: bearer token header, but I cannot seem to find a way to get the auth token from the current user in the Unity Firebase API.
I imagine that I am stepping further outside the realm of firebase unity API and more into google cloud/identity platform
You can retrieve the ID token of the current user by calling TokenAsync() on their profile.
That's the value you need to pass along in the Authorization header of the call to Cloud Functions, where you can then access it in you Callable Cloud Function.
Alternatively you can implement a regular HTTP Cloud Function, pass the same in whatever way you see fit there, and then on the server decode and verify the ID token with the Admin SDK yourself.

Is it possible to only accept function calls from my app in Firebase?

I am creating a game in Unity where the user can contribute with levels using a Level Creator system.
My application is setup in a way that I just need to call the Cloud Function with the level info, and it handles duplicate entries and saves it to Firestore. All of this works perfectly.
My question, basically, is: can I have my functions only accept calls from my game? (without having my users registered?).
Naturally, I am using functions.https.onCall((data, context) => {}). In the documentation for Firebase, I noticed they use context.auth to check whether the user is authenticated or not. However, I am logging this value to the console and it appears to be undefined.
I am also confused with this line, from the same link:
With callables, Firebase Authentication and FCM tokens, when available, are automatically included in requests.
Maybe context.auth is not defined because my game isn't yet in Google Play / Apple Store? Any ideas?
Thanks to the new feature called Firebase App Check, it is now actually possible to limit calls to Callable Cloud Functions 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 Doug describes in his answer, so that you have another shield against abusive users that do use your app.
It's not possible to restrict invocations of a callable function to just one app, and it doesn't matter if the app is published to any stores. Once you deploy a function, it's accessible to anyone with an internet connection.
The best you can do is require your users to be authenticated with Firebase Authentication in your app, then check context.auth in the function to determine if the it should do what the user wants. context.auth will be undefined in the case of no authentication. If your code determines that the function should not go any further, you can return early. But the function is still invoked.

Firebase HTTPS callable functions being called by unauthenticated end users

I have doubts on the calling of firebase functions (gcp functions).
According to here: https://firebase.google.com/docs/functions/callable,
when HTTPS callable functions are being called, the functions.https.onCall trigger automatically deserializes the request body and validates auth tokens. Then in this case, if an unauthenticated end user called this function, is this function being triggered or not? In other words, will I be charged on this calling?
Its true that it does validate the auth tokens for you, but what your function does with those auth tokens is up the the function. By validating them, the framework ensures that invalid auth tokens won't look like an authenticated user.
Notably, the documentation states:
With callables, Firebase Authentication and FCM tokens, when available, are automatically included in requests.
The key to your question is when available.
If validating that the request was authenticated is important to you, then you need to check the variables that firebase provides in the context parameter. (See the API definition of the CallableContext object that is passed in. You are able to pull things off such as the uid (as auth.uid on the second parameter to the function), etc.
In short, the function certainly is executed, and if it does anything or not for an unauthenticated user depends on how it is written.
You can safely expect that the invocation itself is still is accounted for in your free tier quota or as a billable invocation -- there isn't anything at all that says that callable functions have to be authenticated, and there are many possible uses for non-authenticated callable functions (e.g. you want to protect a certain part of the database to only be accessed by server-side code, even if unauthenticated users run it).

Firebase Cloud Functions setting environment configuration within a cloud function

I'm using cloud functions that call an external service that uses OAuth2 Security. Each invocation of my cloud function first, authenticates and gets an access token for the subsequent API call to the external service.
The access token expires in 30 mins, so to avoid token expiration, each invocation I get a new token.
I'd like to use the cloud function scheduler to get the access token and save it to the cloud function config, I can schedule this to happen every 25 mins. This would avoid each invocation requiring to first get an access token.
It does not look like the cloud function environment config allows programmatic updating of config within a cloud function.
https://firebase.google.com/docs/cli/#functions-commands
Anyone solved something similar?
UPDATE: As following further docs, the cloud function needs to be deployed again for the configuration update to occur. I think the solution to this question is likely a CI cronjob, that gets an access token, updates firebase cloud function configuration and redeploys the cloud functions.
I think that trying to update the configuration of the function, or redeploying the function altogether, isn't really the best idea here. You're probably better off just storing the information in a database or some other shared location, then each function can query that to get a hold of the token and its metadata as needed. The function can store the token in memory for as long as its known to be valid so that it doesn't have to be fetched for each invocation.

Avoid spamming to my API that build with Firebase Function

I am building some internal API for my apps/website with Firebase Functions. Internal API as in to let my apps/website to process something on server side, its doesn't mean to open to public use.
My Apps is built with ionic and website is built with angular.
I noticed the one of Firebase Functions Pricing calculation include "Invocations". Is that Invocations means every time when I call the API equal to 1 Invocation? If yes, then the API might be abused by end user, since they able to view the website source and found the API.
I been searching solution in google, some of them suggest to enable authentication and cors, to avoid abuse of the usage. But authentication and cors still counting the Invocations right?
My code structure:
client call API by get/post method, pass user TOKEN that get from Firebase Authentication
request reach the Firebase Functions
server will check the preflight info by using CORS, as well as validate the TOKEN.
Return error if didn't pass on the (3), else proceed to execute the function.
So I assume if end user inspect my web source code and get the API URL, they can simply spam my API right? Then my bill will burst because of the load of Invocations.
If you suspect that your project is being abused, which is always possible, contact Firebase support to work towards a resolution.

Resources