Skip to main content
UnifiedPush
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage
Edit page

Push notifications, security and privacy

How secure is UnifiedPush?

It’s a legitimate question that comes up from time to time. While the question is fairly short, the answer requires a few details. Behind the question of security, it’s also often about privacy.

Security and privacy

When we talk about the security of a protocol, software or hardware, we mean the ability to prevent unauthorized access. We generally evaluate security in terms of the ability to preserve the confidentiality, integrity and availability of a system. In other words, we want to be sure that an unauthorized actor cannot read our data, modify it or render our system inaccessible. Other aspects may also be taken into account, such as the ability of an unauthorized actor to increase our bill for a service.

When we assess the security of a system, we do so against a particular type of adversary, and this often depends on context, which can modify the impact of vulnerabilities. A vulnerability allowing any user of a server to view the photos of other users has no impact if you are the only user of the server. It is therefore important to model threats in order to understand what is being assessed.

Privacy, meanwhile, is the right to choose what information about you and your relatives you share with whom. It’s the ability to reduce the amount of data exposed, even to authorized parties. If you have a joint bank account with your loved one and want to give them a surprise gift, you probably won’t want to use that joint account to pay for the gift. In this case, cash can provide the privacy you need. Your bank account is secure because only authorized people can access its data, and your loved one is authorized to do so. But you don’t want to reveal where and how much you spent on the gift. Privacy is about reducing the amount of data shared to what is appropriate for a service.

Privacy and security are often associated, because privacy can improve the security of a system, and privacy requires security. If your cloud backup system is breached, the impact is less if backups are end-to-end encrypted, as only your device has the keys to decrypt the data. But the key must be stored securely, so that it cannot be read by an unauthorized actor.

Push notifications

Push notifications are relatively short messages sent by an application’s server to the (usually) mobile application through a push service. A push service is always reachable and forwards received messages to the mobile application, even if the application is not running. This method is very useful for obtaining “real-time” events efficiently, particularly used for instant messaging applications.

Without push notifications, applications would either have less instant notifications, by fetching updates periodically, or would increase their battery consumption by maintaining a constant connection with their servers. The first solution is appropriate when events don’t need to be instant - for example, it’s acceptable for your phone to check for system updates every x hours. The second solution is appropriate when battery and data consumption are negligible compared to actual usage: maintaining the connection should be at a minimum efficient, and applications should be used on a daily basis. It’s perfectly acceptable for the messaging app you use all day to drain a few percent of your battery a day for that connection, but it’s different if you only receive one message a week on that app. What’s more, we all have many applications that we rarely use.

With push notification, a single application is responsible for maintaining a constant connection to its server for all the others. The servers of the other applications notify their mobile application by sending a request to the push server.

In the context of push notifications, we can identify different legitimate parties:

  • the mobile application, which receives push notifications
  • the application server, which sends push notifications
  • The push service, the application installed on the device which is responsible for maintaining a connection with the push server and transmitting push notifications to other applications
  • The push server, the Internet-facing part of the push system that receives push notifications from the application servers
  • The device’s operating system, which is considered trusted.

We can identify two types of threat actors:

  • Unauthorized actors from the Internet: they may try to exploit what is exposed on the Internet.
  • Malicious applications installed on the same device: they may try to exploit inter-process communications (IPC). Privilege escalation from this application is excluded, as the system is considered trusted.

For the application that uses the push system, the push system may not be trusted for a number of things too. As with all parties, all others aren’t trusted at some point.

Push notifications and security

The push service and applications must be able to communicate with each other, using inter-process communication (IPC), and it must not be possible to misuse it to :

  • read the contents of push notifications from other applications
  • send fake push notifications to other applications
  • obtain the secrets needed to send push notifications over the Internet to other applications
  • unregister other applications
  • rate limit other applications, if a rate limit exists, for example to refuse registrations of other applications.

The push server is accessible from the Internet for two reasons. The first is to let the application on the device to connect to be notified of new events and to add or remove subscriptions. The second is to receive push notifications from other application servers. It must not be possible for an unauthorized actor to misuse them to :

  • send push notifications to applications
  • access the content of push notifications
  • delete push notifications
  • unregister an arbitrary application
  • rate limit an arbitrary client or application.

Another interesting point to analyze is: if something is compromised, can it be used to target other systems? In the context of push notifications, this is a relevant question for the push service.

Google notifications

Google notifications, named Firebase Cloud Messaging (FCM), formerly Google Cloud Messaging, relies on the Play Services. These services are applications that are not part of Android, but are often pre-installed (with privileges) on your device. These applications are generally not included in alternative versions of Android, or their installation is optional.

The IPC calls are protected by different means:

  • Broadcast intents are used for IPC, and they reach the targeted application only. Other applications aren’t able to read the content of IPC calls.
  • Requests to the Play Services are sent with a PendingIntent. During registrations and unregistrations, the identity of the creator of the PendingIntent is used to get the sender of the request. But as stated per the documentation the PendingIntent you receive from an application could actually be one it received from another application, meaning the result you get here will identify the original application. This solution is not ideal, as PendingIntents sent for another reason can be used to unsubscribe their creator from push notifications, or to reach the rate limit.
  • Requests to the subscribed applications rely on permissions (com.google.android.c2dm.permission.SEND) to be sure the push notifications come from the Play Services. It isn’t possible to have 2 applications on the system providing the same permission. This is a good solution for Google notifications because it is designed to be provided by a single implementation of the service.
  • The Play Services also relies on intents received from the system when applications are uninstalled, or when their data is wiped. These privileged intents can’t be sent from regular applications.

On the (push) server side:

  • Push messages to the FCM server usually follow the FCM API, and need to contain a secret token provided by Firebase. It prevents unauthorized actors to send push notifications to applications. It is also possible to send WebPush requests, then the requests rely on VAPID, and the application server needs to have a private key. Using WebPush for Google notifications has been detailed in the blog post about push notifications for decentralized services.
  • Other requests are authenticated from the client, the Play Services application.

The push service for Google notifications is integrated into the Play Services application. This application supports many different features in addition to push notifications, and requires many different permissions to do so. What’s more, the application is designed to be installed with system privileges. This means that an actor accessing the application, for example by exploiting a bug, will have plenty of rights to do other things on the system. Dividing the application into several services would enable better compartmentalization, to which the principle of least privilege could be applied.

UnifiedPush

UnifiedPush is a push notification protocol that allows users to choose the service they want to use. Therefore, users may install different applications providing push notifications (often called distributors). UnifiedPush is actually 2 different protocols, one for Android, another one for Linux.

For Android, the IPC calls are protected by different means:

  • As of Google notifications, broadcast intents are used for IPC and reach the targeted application only. Other applications aren’t able to read the content of other IPC calls.
  • For the registration, the application sends the intent with a flag that shares the sender real identity to the push service, if the device is recent enough (Android >= 14). For older devices, the service identifies the sender of the requests using an attached PendingIntent. As said earlier, the PendingIntent you receive from an application could actually be one it received from another application, meaning the result you get here will identify the original application. PendingIntents could be passed to reach the registration rate limit of a distributor.
  • A secret token is generated and shared during the first registration call. This token is used to check the requests’ authorization from the push service, and to unsubscribe applications.
  • The Push services may also rely on intents received from the system when applications are uninstalled, or when their data is wiped. These privileged intents can’t be sent from regular applications.

For linux, IPC is based on D-Bus:

  • D-Bus calls reach the targeted application only too, and other applications aren’t able to read the content of other calls.
  • The push service can use sandbox properties to control the origin of registration requests. For instance it can get the caller PID and control the flatpak info. If this isn’t implemented and the distributor implements rate limits for the registrations, another application may be able to reach the limit for another application.
  • As of Android, a secret token is generated and shared during the first registration call. This token is used to check the requests’ authorization from the push service, and to unsubscribe applications.

On the push server side:

  • Push endpoints, the URL where applications send push messages, are Capability URL. This kind of URL works as a shared secret between the application and the push system. It usually contains a token and can be re-generated if necessary.
  • Push servers are supposed to support VAPID. VAPID is a standard (RFC8292) providing access control based on asymmetric keys. Not all providers check VAPID authorizations, but UnifiedPush specifications even allow distributors to require it. The application registers with the push service for a given public key, then the push server will only accept requests with a signature made with this private key, for the given push server. This is an additional protection, if the push endpoint is leaked, it cannot be used.
  • UnifiedPush requires push notification encryption, following web push encryption standard (RFC8291). Encryption is based on asymmetric keys: when the application receives its endpoint, it sends it to the application server with a public key and an authentication secret. The application server uses this to encrypt push notifications. If it is not correctly encrypted, the notification is rejected by the application. Consequently, the push server itself is not supposed to be able to send valid push notifications. As if VAPID wasn’t being used and the push endpoint was leaking. Please note that some applications do not yet encrypt their push notifications.

The push service (or distributor) is generally an application dedicated to UnifiedPush. This application can therefore restrict their rights and permissions to the strict minimum, reducing the risks in the event of compromise.

For applications

Other aspects can be analyzed, such as the possibility of using push notifications as a DDOS amplification vector or for Server-Side Request Forgery (SSRF, a bug exploited to send requests from the server to resources inaccessible to the attacker, such as resources in the server LAN). For both these reasons, it is recommended that the application server:

  • rejects push endpoints pointing to private IPs, with an option to allow some IP/hosts for self-hosters
  • doesn’t follow redirections for push requests
  • sends a single push request with a token to validate a push subscription. Actual push notifications will be sent once the subscription is validated. It’s like what usually see to valide email addresses.
  • removes push subscriptions that return a 404 HTTP code
  • disables temporary push subscriptions when some requests fail
  • batches some notifications or include a timeout between 2 notifications, if possible

Push notifications and privacy

As mentioned above, privacy is about the right to choose what information we share about ourselves and our relatives, and with whom. It’s about reducing the amount of information shared, even with authorized parties.

Content of push notifications

The content of push notifications is obviously the first thing to think about when analyzing privacy risks for push notifications. There are 2 ways to protect the content of push notifications: (1) by encrypting push notifications, or (2) by sending dummy events used to wake the targeted application which will synchronize on push.

UnifiedPush requires push notification encryption following web push specifications (RFC8291), but some applications don’t do it yet. Google notifications don’t have any requirement for push notifications encryption. Consequently, the protection of push notification content depends on the choice of application. Content is not necessarily exposed by unencrypted notifications, if the notification is a simple ping to wake up the mobile application, as Signal does.

Metadata

Some metadata are exposed to the push server. Metadata is data relating to a data : when and how often push notifications are sent, where they come from, etc. For push notifications, metadata can provide the push server with information that can be used to :

  • know what application is targeted
  • link an application account to a push service account
  • link to a real identity or an online identity
  • link the activity of 2 different users

The targeted application is usually known by FCM with Google notifications, because it is recorded during the registration of the project in the Firebase console. Also, the Play Services share the list of your applications with their server. UnifiedPush per its architecture doesn’t have this kind of registration. But even without it, the push server (Google, UnifiedPush) is likely able to find out the application based on the request fingerprint (user agent, origin IP, TLS fingerprint, authorization header), especially for centralized applications. Finding the targeted application on the basis of the request’s fingerprint requires more resources than declaring the targeted application during registration. If the push server doesn’t actively try to find this information, the required information (the fingerprint) may not even be recorded.

Linking your application identity to your push service account can be done by different means. If your application server cooperates, this is easy to achieve, as the application server should be able to push to a single device, identified by a token or a capability URL. Alternatively, this can be actively achieved by sending an event on the application that triggers a push notification from the server. The push server is able to identify the accounts that received a push notification after the event. The operation can then be repeated until only one account has been isolated. The size of the (encrypted) push notification can also be used for this purpose.

Application servers can implement a few workarounds to make correlation a little more difficult, such as fixed-length push notifications, or certain batches to send multiple push notifications at the same time, not directly after the event.

Linking your push service account to your real identity or your online identity depends again on your push service. If your push service is used for other purposes and uses an identity, push notifications are trivially linked to this identity. For Google notifications, Play Services are generally linked to an online account as a minimum: they are usually linked to your Google account which is likely linked to your real identity. They are also often linked to an advertising identity, shared across applications. For UnifiedPush, if your distributor is used for another purpose, this identity can be linked to push notifications. The ability to link an application identity to a push account (previous point) may also be used for this purpose.

Linking the activity of 2 users can be used to know who is talking to whom. This is based on correlations between the activity of two accounts. If two accounts share several activity peaks, it’s likely that they interact with each other, and the more you analyze them, the more accurate your conclusion will be. It’s likely that your application server already knows or is already able to make the correlation. The push server, if it is able to know the targeted application, can also perform the correlation for users using the same push server. Different push servers may be able to cooperate to extend their analysis.

As a result, the more push servers there are, the more difficult it is to carry out mass surveillance on the basis of push notifications. And the more centralized push notifications are, the easier it is to use them for this purpose.

The last kind of metadata shared to push servers is regarding the user device. Indeed, the user needs to be constantly connected to their push server to be notified when the server receives an event. If you use FCM, you are constantly connected to Google servers. This allows the push server to know your different IPs and how often they change, and some of your habits can also be deduced from when the connection starts and stops.

Metadata analyze and activity correlation may sound a bit paranoid, but they have been documented. In a letter to the US Department of Justice, the US Senator Ron Wyden said that:

Government agencies have been asking Apple [for iOS] and Google for metadata related to push notifications to, for example, help tie anonymous users of messaging apps to specific Apple or Google accounts

Their monopolistic position give Google and Apple (for iOS) “a unique position to facilitate government surveillance of how users are using particular apps”. Without that monopolistic position, the analyze would have required cooperation between push servers to allow that mass surveillance. One thing to keep in mind is the more actors it requires to cooperate and the more resources it needs and the less likely it will be deployed massively.

Information collected by the push service

To operate, the push service doesn’t need much information. The service can be a minimal app, easy enough to review, if the source is open.

But as with Play Services, the push service can be included in an application used for other purposes. And for these other reasons, it can collect much more information, such as the full list of apps installed on your device, your phone’s IMEI number, your contacts, your location, etc. Because of this lack of compartmentalization, if you need the push service, you have to take the whole package. And if, like Play Services, the application is installed with system privileges, the amount of information available can increase.

Some alternative versions of Android such as GrapheneOS include a compatibility layer to sandbox Play Services as an unprivileged application. Other projects such as microG aim to reimplement the services to reduce data collection.

Self-hosting the push server

Lastly, self hosting the push server, may share some data to your application server. Self-hosting this service shares the same risks with any self-hosted application, publicly exposed on the Internet, like e-mail, instant messaging, website, and so on. Your push server domain will be shared to the different application servers, it may be used to link to your (online) identity. If your domain is 0639981234.fr, your application can guess your phone number. If you expose the service from your residential IP directly, it will be known to the applications servers.

It is also good to remind that if you don’t use a VPN, Tor, or another proxy technology, most applications are already able to know your (residential) IP, using client connections, which aren’t necessarily related to push notifications.

If you wish to self-host your service but you want to hide your IP, some solutions exists. You can use a port-forwarding solution, or a reverse proxy. You can also use a VPS to host the push server directly, a port-forwarding solution, or a VPN.

How likely these information will be used, shared, to how many parties ?

One important thing about privacy is being able to choose what information we agree to share with whom, and for what. It is therefore legitimate to wonder about the likelihood of our data being shared and used for other purposes. If your push service provider is an advertising company (such as Google), this information is probably used, and you may even have agreed to it, in the terms of service. If you host your own push server, it’s unlikely that you’ll cooperate with other push providers to enable government agencies to carry out mass surveillance.

If a provider has been working with different government agencies, may it be for legal reasons, there are high chances they will continue to do it.

Resilience

While this post deals with the security and privacy of push notifications, it’s worth remembering that they are not the only prism through which to analyze a solution.

Have you ever wondered how you’d use your phone in a network where centralized services aren’t available? Whether it’s in a non-Internet network, on a trip where US services aren’t accessible, or because you live in one of these regions?

If you’re a developer, do you know what happens if one of these critical services becomes chargeable or increases in price? Can your users migrate without your intervention if these services become unavailable to your application? Do you need to implement something, and how quickly can it be deployed?

Self-hosting helps us understand how our tools work, allows us to experiment and gives us some control over them. The possibility of self-hosting should also prevent abuse: in the event of disagreement with the main provider, it is possible for other actors to provide the same service.

Conclusion

We don’t expect all mobile users to migrate to UnifiedPush tomorrow. But wherever possible, we’d like to be able to use it. Google notifications support is a good thing for the majority of Android users today, UnifiedPush support on top of that should meet the needs of users without Play Services, users who don’t want to or can’t use Google services, making Play Services an option instead of an obligation.

How secure is UnifiedPush? At least we’ve got a blog post to answer that question now.