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.