Search code examples
firebasegoogle-cloud-platformgoogle-cloud-functionsfirebase-hostingfirebase-app-check

How to restrict Firebase Cloud Function to accept requests only from Firebase Hosting website


I have a Node.js API (built with Express.js) hosted on Firebase Cloud Functions and an accompanying web application hosted on Firebase Hosting which is supposed to interact with the aforementioned API.

I would like to restrict calls to the API so that only the web application would be able to call the cloud functions. How can I achieve that?

What I have tried:

  • using the App Check or more precisely Google's reCAPTCHA v3 for web apps. I have whitelisted the domain of the web application and have activated App Check token validation server side as well. The problem with App Check, however, is that I am able to obtain the reCAPTCHA attestation token from the browser (after authenticating through the web app) and use that with requests made from anywhere. This enables bombarding the API from outside the web application and defeats the purpose of using App Check in the first place.

    Something to note here, the documentation for activating App Check in Cloud Functions instructs the usage of functions.https.onCall(). However, since my API is built using Express.js, I had to use a workaround to be able to use functions.https.onRequest() as instructed here.

  • restricting the Cloud Function from Google Cloud console to allow only clients of the same project to call the function as instructed here. Unfortunately, my web application hosted on Firebase Hosting does not seem to belong under the same Google Cloud project. Apps hosted on Firebase Hosting do not appear in Google Cloud console. Furthermore, after adjusting the Ingress settings of the functions to "allow internal traffic only", I am receiving CORS errors when attempting to access the API through the web application. I am unable to access the API from anywhere else though, which is partly the desired outcome.

Before anyone proposes limiting the domains in CORS options from within the API, while this might serve the purpose of restricting access to the API endpoints, it still would allow calling the function rapidly and thus, potentially, racking up the bill.

I am grateful for any suggestions!


Solution

  • Firebaser here.

    This is a great question! Doug has already made some great points above, and I'll just add to that by saying that the TTL on App Check tokens reduce the replay window that you observed in your first bullet point, and this TTL is configurable.

    The default TTL for reCAPTCHA v3 is 1 day to protect against running out of quota, but you can set a shorter TTL to increase the cost for an attacker trying to set up a replay attack. But please do be mindful of the associated trade-offs as described in the documentation. You can read about the associated quotas and limits here.

    Unfortunately, web applications redirected from Firebase Hosting can't hook up to the GCP internal network. App Check is actually exactly what you are looking for in this situation.

    Finally, because we are continuously working on improving the App Check platform, the comments you leave here are valuable for us as we decide on what anti-abuse features we want to work on next.