allAuthenticatedUsers for a cloudFunction to send a push notification: perl client side code - firebase

I have written a HTTP cloud function called send_push. It basically receives payload from a perl script and sends out push notifications via FCM to the tokens provided. Tested it in unauthenticated mode and everything works well. This "perl script" is open source. People download that perl script and use it to send notifications to my mobile app (which they buy from the app/play store). So obviously, the perl script cannot come with any of my secrets or service accounts.
I now want to add authentication to that cloud function. My goal is to allow my function to be called by any user who is signed into google using their own credentials. To enable this, I've gone to https://console.firebase.google.com/u/0/project/<myproject>/authentication/providers and enabled "Email/password" and "google" in the hopes that anyone who signs up using an email/password or directly via google login can then invoke my function. I've also enabled allAuthenticatedUsers for my send_push function and removed allUsers
Have I made the right assumptions? I've been going around in loops trying to parse the cloud functions authentication documentation.
If I have made the right assumptions, what libraries can I use on the perl script side that can prompt the user to enter their login credentials (via google or email sign up) and then use that data to generate and refresh tokens? They won't have gcloud installed, so I can't do things like $(gcloud auth print-identity-token) for authentication, which I think anyway is for developers.
Note that the sample cloud authentication code shows how my endpoint can authenticate against firebase users that have registered with _my_app. This is not what I want.

Related

Firebase Admin SDK security best practice for push-notifications

I want to let my customers send push notifications to their users. I am using Firebase Admin SDK for that, which requires the "service-account.json" file. For security reasons this file should not be shared with others. How could I make this feature available to my customers, without sharing any "secret" information?
If you want to allow your users to send push notifications, you'll have to make a custom API endpoint that you can call from the application they use. It's quite common to use Cloud Functions or Cloud Run for this, but any trusted environment you may already have can work too.
By running the code that sends the message in an environment only you can access, allows you to securely use the Admin SDK that has full administrative access to your Firebase project.
Then when this code gets a request from a user running your app, it needs to check whether this user is authorized to send this message to the user(s) they are trying to send this to. Exactly how to check authorization depends on your app, but some things to consider:
Is any user allowed to send a message to any other user, or is there some mechanism where they opt-in to receiving messages from each other?
Can any message be sent, or is there some mechanism that validates the messages, for example by detecting whether any foul language is used?
These are just some examples of the types of checks you might want to do, and the actual list completely depends on your app and its use-cases.

Protect Firebase callable functions from man in the middle

I have made my mobile app using firebase on iOS & I use callable functions to communicate with database.
When I try to perform a “man in the middle” attack/move using a simple app as Charles, I can see all my calls with the data I send, in plain text. When I use a well know app like iTunes I cannot decrypt anything (which I think is what we call ssl pinning)
I have 3 questions:
does firebase cloud functions (https.callable) handle ssl pinning ?
if not how can I protect from this ? Using node for my function, is it possible to request a ssl certificate from firebase and link it to functions ?
Does the mobile Sdk request are pinned ? I cannot see anything about read calls on my sniffing app.
Thank you all.
As per this post here by Doug, all data in and out of Google is encrypted (including the client SDKs). There is simply no way around this.
Now, you can take this a step further and prevent abuse by configuring App Check which, according to the documentation, provides an additional layer of security against billing fraud and phishing.
However, you will still need to check the authentication token (automatically passed in with onCall functions) to make sure the user is authorized to execute the functions they are calling.

Does Authenticated Cloud Run instance natively support Firebase Authentication?

I have read this page a few times it implies and does not imply that if I enable authentication when deploying a Cloud Run instance I can use Firebase Auth to get through to the service.
I tried passing in a valid Firebase user idToken and did not get through. Was I doing something wrong or is the only way to get through to Cloud Run when Authentication is enabled to use google sign in?
Steps to reproduce:
When deploying to Cloud Run select Yes for authenticated
Generate a firebase auth token using REST call from here
make api call to Cloud run instance using header bellow and ID_TOKEN from step 2 above
Authorization: Bearer ID_TOKEN
According with the comment, the use case is to authorize only the registered, and the authenticated user (with Firebase auth), to use a Cloud Run endpoint deployed privately.
You can't do it directly, you need to use an additional layer. Here I propose to use Cloud Endpoint. I wrote an article on this to set up an authentication with API Key.
You have the principles of Cloud Endpoint there. You simply have to change the security definition from API Key to Firebase auth. You can found documentation here
Note: The authentication methods can evolved the next quarters. Stay tuned

Authenticate IoT Appliance Using Firebase Auth

I can't figure out how to authenticate my IoT appliance to call Google Cloud App Engine APIs I've written using Firebase Auth.
We currently do this with our browser app using Firebase Auth tokens. We use the username and password to issue a token and then use that token during the life of the session to access APIs from our browser app.
This doesn't translate well to our IoT appliance as there is no username/password - so we are thinking we will need to use Firebase custom tokens. Unfortunately these tokens expire every hour - so we will need to use the Firebase Auth APIs to renew the tokens automatically - we think this is the way this works based on documentation.
A constraint we have is that this appliance doesn't have any user experience but instead needs to be able to restart at any time and reestablish it's authenticity with the server by retrieving a fresh token.
I'm having a hard time finding an example of how to do this - and I'm hoping someone can give me a simple example or some clear direction on how to keep a authentication token current while the appliance is on and establish a new one if it needs to restart.
Thanks!
Have you looked at Cloud IoT Core as an option? It handles the authentication piece for you without user/pass (uses JWT), and is designed for IoT. A quickie Cloud Function can bring your telemetry data into Firebase/Firestore very easily.
Another option would be to create a service account with permissions to write to AppEngine. Check out this link: https://cloud.google.com/docs/authentication/getting-started for some documentation on how to authenticate using a service account.

Firebase Admin SDK create user using providers

I am trying to create a REST API for my app using Firebase Cloud Functions. I know how to use Admin SDK in Cloud Functions. It does have API to createUser. My front end app lets users sign in using Google and Facebook but I am not sure how to put it all together.
My app has successfully implemented Sign in with Google and Sign in with Facebook but how and what data do I transfer over to Cloud Functions (or any REST API Server for that matter) so that it could create a user in Firebase with appropriate provider.
Update for more explanation
I am creating an app for iOS and Android with some sort of cloud based backend. Right now I am experimenting with Firebase but I do not intend to tightly couple my apps to Firebase and hence do not want to pull Firebase-iOS and Firebase-Android SDKs into my app code. I want the ability and freedom to switch my backend over to AWS or Azure without changing frontend code.
The one (and only?) way is to create a server that will expose REST API endpoints and do the work on my behalf that usually SDK does. To achieve this, I am using Cloud Functions but that shouldn't matter as long as I have API to talk to actual cloud.
After putting that explanation, now my question is how do I let my users login to app using external providers like Google and Facebook and still achieve what I am trying to do. When I let users sign in with providers, I do not have their password to send to backend to create a new email/password user.
The sample code that best illustrates what you want to do here on GitHub.
It shows how to create an Express app that handles HTTP request pages. Learn more about Express to configure it for wildcards are needed.
It accepts and checks authentication tokens in HTTP requests from Firebase Authentication to validate the end user responsible for the request.

Resources