Web Push vapid key generation logic - push-notification

I have multiple https domains for sending web push notifications. But i will send web push notification from one server. I know why it is use and i read some documents about it. But i didn't see anything about this approach. I generated vapid key from my server just once. I tried to send push notification with these keys and i got notification successfully. But i have 2 question for you.
Should i generate different VAPID key for each domain ?
Can i generate just one VAPID key and use all domains ?

For security and isolation, you should create a different VAPID key for each separate project. If the same project uses multiple domains or subdomains you can use the same VAPID key and there isn't any problem.
Yes, you can. However if you deal with completely different websites this is not recommended: you can improve security and data portability by using different VAPID keys.

Related

Prevent front-end generated email sign-in links when generating and sending these via backend

I am using firebase admin sdk on the server to generate sign in links and send them out via custom SMTP api.
I just glanced at https://firebase.google.com/docs/auth/limits and I am well within these, but I believe there is nothing stopping a malicious third party from creating/requesting sign-in links via front end code. Is there a possibility to disable this functionality so it is only available to admin acc?
Additionally, I'd like some emails (i.e. multi factor enrolment) to not be possible, but again, given that someone can obtain some of my firebase front end details, they technically can send these?
You can restrict the API key from accessing an API (e.g. Identity Toolkit) but not disable a single method of the API for client.Sign up and delete user can be (that requires upgrading to Identity Platform) .
Firebase generates an API key when you add a web app. You can either update that or create a new key from API Credentials console.
You can then restrict what the API key in Firebase web config has access to:
However, Firebase Auth Client SDK will not work as Identity Toolkit is not selected. You'll have to proxy the requests through your backend and use a different key that can be used from your server's IP only.
Firebase Admin SDK will still be functional as usual so you can use that to perform other operations like updating/deleting users. You'll just have to write APIs on your backend for what could have been done using client SDK directly (or use Admin SDK when possible).
It might be a lot to update and I would not recommend unless you are facing rate limiting issues where Firebase Support should be able to help.

How can I securely hide api keys that need to be accessed by the client in Nextjs?

I am developing a web application using NextJS. I am using firebase, sentry.io and infinite scroll in my project. When the application first runs, my data from the backend comes as server side. If the user scrolls, my new data is necessarily brought as a client side. I defined my key in the .env.local file with the prefix NEXT_PUBLIC since this API will be requested on both client and server sides.
Wouldn't defining it as NEXT_PUBLIC show my api url in the network?
I need to collect events with firebase for user actions. I have to access Firebase as client side. That's why I define my keys with the NEXT_PUBLIC prefix. For example: NEXT_PUBLIC_API_KEY
In such a case, my api key will appear on the network again. Isn't this a security issue?
How can I hide Firebase API Key?
I collect the errors that occur in the project with sentry.io. Likewise, I need to access sentry.io as a client side. When I perform the above scenario, users will access my API key.
If the secrets we define as NEXT_PUBLIC become public, what is the logic of defining them?
I need to request client-side for Infinite scroll and firebase, how can I secure the secrets I use at this point?
I will deploy my projects with docker. Where should I specify these env variables?
Well you can use Google Cloud Secret Manager to store your keys and you can use the Client Library to fetch the keys as you want.
References:
Secret Manager Docs
Secret Manager Client Librarirs Docs

Secure communication between Flutter App and Web PHP

I'm learning Flutter myself and need some expert guidance on the right way to do what I want.
I would like to allow the user of my Flutter application to securely send some sensitive data (e.g. email, phone number, name etc.) to my PHP based website (with REST API) and then, after some time, I would like to send a reply (e.g. . text) from my website to the sender's device and displaying it on the User's screen.
I suspect I should use Firebase Cloud Messaging for this - am I right?
I found tutorials that explain how to send data from Flutter-> FCM and from PHP(curl)-> FCM. But I can't find the tutorial explaining how to send data from Flutter-> FCM-> PHP?
Firebase Cloud Messaging is typically used to send messages from the server to the application, when the user may not be actively using it. While it can be used to send messages from the client to a server, it is much less common for that.
That's because calling a PHP API from your Flutter app is no different than retrieving any data from the internet, and can be accomplished in a multitude of ways. One of the simpler approaches is documented in Flutter's fetching data from the internet page and uses the http package.

FCM Security: Prevent multiple senders from pushing notifications to all devices?

As part of our solution, we want to deploy an FCM "app server" at each of our customer sites. Each customer site has their own users with their own devices using our app. However, we want to make sure that if one of the customer sites is compromised, an attacker could not abuse the FCM "app server" (e.g. by sending notifications to all devices at all customer sites).
Instead of sharing credentials between all customer sites, we are thinking of generating a unique server key for each customer site. That way if one customer site is compromised, we can disable that server key and stop any more FCM notifications from being sent.
Question: Can we be sure that an attacker cannot send global notifications to all devices?
Assuming an attacker has a server key and access to one customer site "app-server", can they get a list of all the registered devices?
Is there a default notification "topic" that is sent to all devices? (e.g. /topic/all or /topic/global). If so, can we disable that default topic?
Instead of sharing credentials between all customer sites, we are thinking of generating a unique server key for each customer site. That way if one customer site is compromised, we can disable that server key and stop any more FCM notifications from being sent.
If by "we are thinking of generating a unique server key for each customer site" you mean that you'll simply create a Firebase Project for each customer site, then I think this is the correct approach.
Can we be sure that an attacker cannot send global notifications to all devices?
An app can receive messages from a different Sender by implementing the getToken(authorizedEntity, scope) which will generate a different token for each Sender. In order to negate this action, you could simply call deleteToken(authorizedEntity, scope) (my reference).
This would invalidate the token for that corresponding sender (which is what they probably have and should be the only one on their App Server), which would automatically disable them for receiving messages to your App.
So as long as you're able to remove them as a valid sender from your app, then it's all good.
Assuming an attacker has a server key and access to one customer site "app-server", can they get a list of all the registered devices?
This depends on how the App Server is implemented. If the customer's App server is only used for sending messages, but the tokens are stored elsewhere, then probably no. There is no API to retrieve registration tokens on the server side for an App based on the Server Key (see #1 here).
Is there a default notification "topic" that sends to all devices? (e.g. /topic/all or /topic/global). If so, can we disable that default topic?
There isn't. There is the option to send a Notification to a specific app via the Firebase Notifications Console, but if the app doesn't authorize the Sender ID corresponding to that project, it won't receive any messages from it. I've tested this behavior out before posting, so I'm positive that this is how it works.
There is no way to restrict a server key to only allow certain topics/devices/etc.
I would consider using Cloud Functions for Firebase to solve this a different way. You could build an HTTPS function that took per-site authorization tokens (by any means you deem fit) and then that function calls through to Firebase Cloud Messaging to actually send the push notifications.
This way, you have complete control over what kinds of push notifications can be sent by the "client" sites, and you don't have to worry about cascading security problems in the event a client site gets compromised.

Manage server keys in Firebase Cloud Messaging

I've just opened a Firebase Cloud Messaging project intended for Android push messages.
The gear icon shows one server key (obfuscated here for obvious reasons):
I would like to have more than one key, so I can distribute them to servers and developers and revoke compromised keys if necessary.
How do I manage (add and delete) server keys in Firebase?
Update:
As of the moment, the way it should be done in order to generate a new Server Key, as stated in the docs:
Starting from Sept. 2016 new server key can only be created in the Firebase Console using the Cloud Messaging tab of the Settings panel. Existing projects that need to create a new server key can be imported in the Firebase console without affecting their existing configuration.
For the project migration steps, see my answer here.
For generating Server Keys, there is no way to generate one in the Firebase Console. It can be done via the Google Developers Console:
Go to your Google Developers Console
On the left-pane, click on Credentials
Under the Credentials Tab, Click on Create Credentials
Select API Key
Steps retrieved from my answer here
After you select API Key, it will directly create an API key without asking what type of key (Server, Android, Browser, iOS) it is. It will only allow you to set some Restrictions that was visible depending on which API Key you intend to generate.
By default, the key generated has No Restrictions, this makes a key vulnerable, that's why it is highly encouraged for you to add a restriction for your API key. In this case, since you are using it for FCM (Server Key is needed), you must add an IP Address restriction and only allow specific server IP addresses.
With that said, I don't know how you plan to integrate multiple server keys to a single Firebase Project though. Why not just make use of the IP Addresses restriction and remove the server IP address that are deemed compromised?
It's not possible to have multiple cloud messaging server keys per project. I'd suggest you to have multiple Firebase projects for your application development staging environments.
If needed, you can then re-generate the server key in the Google Developer Console.
On the top-left corner of the screen, verify that the correct
project is selected.
On the left-side panel, click Credentials.
Under Credentials tab, click Server key (auto created by Google
Service).
Click Regenerate key button
A confirmation box will show up asking if you'd like to replace the current key, then click Replace key button.
Note that the new key will be available immediately. The current key will be deactivated permanently in 24 hours.
After all of these steps, you can check that the cloud messaging server key of your Firebase project is now updated.
In Firebase, the Server Key is auto-generated. If you check out the Firebase project in the Google Developer Console, it will be listed as such. You can then create more Keys from there (but will not be listed in the Firebase Console, from what I can tell).
Basically, you can better manage the keys thru the Google Developer Console.
Hope this helps!
You should avoid distributing API keys for the same project. If any one of those using the API keys are found to be abusing it then the entire project will be throttled, affecting all keys for the project.
If you do want to have multiple developers send notifications to your application then have each developer create a Firebase project then have the client register with each sender ID. You will still have the ability to rotate the API key for each developer, or have the client delete the token for a developer that you no longer want to receive messages from. This way any abuse from one developer does not negatively affect the project as a whole.

Resources