google cloud messaging security - android

Company creates a project and receives a sender ID. Company creates an app, bakes in its sender ID and places the app in the store.
Attacker reverse engineers the app and extracts both the sender ID and the server interface used to receive GCM registration IDs.
Attacker creates his own app, bakes in Company's sender ID and server registration interface, puts app in the store. The attack app basically impersonates Company's real app as far as GCM goes: it registers to receive messages from Company's sender ID and then sends its GCM registration ID to Company's servers just like the "real" app does.
Now Company wants to broadcast some information to all instances of its app. Maybe it's a reminder than an update is available. Is there any way to differentiate the "attack app" (which registered just like the real one) from "real" versions of the Company's app?

I think from your scenario it's not possible for the attacker to send a message to the user even if he has the registration id. The company server which sends the messages they need to authenticate (OAuth2) there account first through Google. So only if the attacker knows the password of the sending party and the registration id than it can send the user. But the password of the sending party of course is never send to the client side.

well, this might even work in a debug version of the attackers app, but he can not put his app in the store. part of the GCM identification is the app id which needs to be unique in the store.

The same problem could also have existed with C2DM, which you can sniff the sender email address, instead of project ID for GCM.
C2DM or GCM, should never be used to send sensitive user information (i.e. account name, private information, etc), it's mainly useful for notification, which the real app can use it to perform further actions.
I can't see how useful a notification can be to a 'fake/hack' app, what are they going to do with 'You have new message' notification?

The GCM Registration ID is requested by Google, requested from the app and submitted to your server. When someone with a different app (but the same sender ID) creates a Regid, it still has to be committed to the server, and you first have to explicitly send a message to that specific regid.
An app installation, whether legitimate or not, can never receive messages it is not authorised for. (Provided you declare and use the C2D_MESSAGE permission)

Actually, google let's you register a Server Key for GCM, which lets you White-List Server IP's...
So you should add your server IP and you would be safe, since only your server is allowed to send messages with that key.

GCM is safe in this case.
You even can't use your Sender ID in your original app before you register the app in GoogleApiConsole. This means you point private key fingerprint in GoogleApiConsole. It's enough.

I would suggest having your own "interim server" which uses the API key (sender ID as you referred to it). Instead of embedding it in the app itself.

Related

Is Sender ID Private?

I have an open source public application that uses GCM push notifications. To register for push, the sender ID is placed into the source code. Is it OK for this sender ID to be exposed publicly? Is sender ID suppose to be kept private? Is there anything bad anyone can do with my sender ID if exposed?
It is fine to expose sender id because it has no meaning without serverkey.
A sender ID is not tied to a unique application package name. In fact, multiple apps can register to GCM using the same sender ID, which will allow the same API key to be used for sending GCM messages to all of these apps. Of course each app will have a different registration ID (even when on the same device).
If someone knows your sender ID, they can register to GCM with that sender ID, but without knowing the API key they won't be able to send GCM messages to either the fake app or the real app. When they register to GCM, GCM receives the package ID of their fake app. Therefore if you send a message to a registration ID of your real app, it won't reach the fake app.
leave it Protected and also try to keep the API key and as well as your server details.
More reference
1
This question stems from not knowing what each of these keys do. This information is relevant for Firebase Cloud Messaging, which replaced GCM.
FCM sender ID
The FCM Sender ID is actually the Firebase project number 😂. To check it yourself, you can compare project_info.project_number in google-services.json/ Firebase project settings page with the sender ID.
It is used by Android clients to identify which application (Firebase project) to register for FCM with, so it makes sense.
It is available in the google-services.json which is not sensitive.
The worst thing a user can do if they know your sender ID is they can register for push notifications from you.
FCM Server key
The FCM server key is sensitive, because it allows users to send push notifications to the devices which have registered.

Should I generate android GCM registration ID app specific or user specific?

I am developing an app which has login functionality.I am generating only one gcm registration ID per app. If other user sign's in in same app he will start receiving notifications intended for the previous user.
How to handle this situation, so that each user will get notification intended for his/her?
Should I generate gcm reg id for each user?
What is the standard way to handle this situation?
You could try the following things:
When the user logs off, send a request to delete the token on your server, and erase it on your app;
Once the user logs off, you could simply remove the association of "User ID" to "GCM Token" (Or Registration ID) on your server. And when someone logs in again, you make a new association to that Token.
The GCM Token is app specific, but the association you make on your server is totally up to you.
And I can't stress it enough, the token generated by GCM is APP SPECIFIC. If your user logs in on multiple devices, your server should handle that, associating the user ID to multiple Registration ID Tokens.
An ID issued by the GCM servers to the Android application that allows
it to receive messages. Once the Android application has the
registration ID, it sends it to the 3rd-party application server,
which uses it to identify each device that has registered to receive
messages for a given Android application. In other words, a
registration ID is tied to a particular Android application running on
a particular device.
And from the docs, your server should also:
Before you can write client apps that use GCM, you must have an
application server that meets the following criteria:
Able to communicate with your client.
Able to send properly formatted requests to the GCM connection server.
Able to handle requests and resend them using exponential back-off.
Able to store the API key and client registration tokens.
Able to generate message IDs to uniquely identify each message it sends. Message IDs should be unique per sender ID.
EDIT: You can read more about GCM here.
For further reading, you could also read more on Device Group Messaging.
You can also download some code samples here.
You should store regID as per user.
This is because there is test cases that user1 logs out and user2 logs in. In that case if you have stored regID app specific and not binding with user then user2 will also get notification.
So you need to store regID as per user , app and as well as device specific.
Of course yes every time someone downloads your app, your app should register them with the GCM and be given a reg token, this needs to be sent to your app server, on your app server you need to sort out who you are sending the notification too. you should probably send some login info and reg token when they login so you can identify each person, then write some php or Jquery to send to individual users or all. you should also send the reg token every time they login as these can change without warning.
Your app server should be able to handle removing unused reg tokens and adding new ones
Each android device generate a Unique GCM reg id. push notification from server side will send according to the device id. So at Login time you can send GCM reg id to your server. So from server side push notification will send to device.., that is actual functionality.
Hope this will help

Register to Google Cloud Messaging from outside of the app

Is it possible to sign up the app for GCM from outside and receive the registration_id having all the information needed?
I mean I could send the environmental variables to the server side which would register to GCM for me, so that I can avoid dealing with these requests on the client-side.
No, it's not possible. The Registration ID that you get from GCM is tied to an application on a specific device. If you would try to perform the registration from the server, how would GCM know to identify the device that the Registration ID is tied to?

Android C2DM, Sender ID in the Push App

The Android C2DM push app that I have developed has the reference of my sender is (example: "sender#gmail.com") in the application side code.
Case 1:
When I install this app on a Android device, the device has a gmail id as "personalid#gmail.com" in Accounts and Sync settings.
App is registered successfully with C2DM but it does not receive any of the pushed messages.
Case2:
When I use the same sender id ("sender#gmail.com") in the Android device's Accounts and Sync. I receive all the messages that I push.
Why case 1 is failing and case 2 (sender id all through) is successful?
Please make sure that you have signed out from built in gtalk application of your phone, if you are not signed out from gtalk app, then it will create ambiguity in between gtalk and ur personal app for messaged pushed from google server so it can not send message to any app and give exception.
For detailed information of push notification , please check https://developers.google.com/android/c2dm/
best c2dm tutorialis ,http://www.vogella.com/articles/AndroidCloudToDeviceMessaging/article.html
This is the way that C2DM works. It makes sense that it works in this way since it requires the email address for both the registration id and authentication token.
When sending a push message, your third party server uses the registration id built on (probably) "sender#gmail.com", and authentication token built on the same email. Google's server looks on your device and tries to find that specific email address account. You can have multiple accounts on the device, but at least one of them has to be the account used to register the device.
Why would Google ask for the email anyway if it wouldn't have mattered? It would have been much easier to use directly the device's unique id.

how users opt-out of c2dm message

we are implementing c2dm to push notifications to users. we want the user to be able to "opt-out" at the beginning. if they opt-in, then we register the device and send the id to our server to store for later delivery and track that by some unique device id.
the problem is that there doesn't seem a reliable way in android to get a device id. everything i've read says, "just generate a guid at first startup of the app". well, this is fine, but if a user starts up the app, opts in, then uninstalls and re-installs the app, then opts out, i have no way of removing that old device (since the device id of the second install is new).
i've tested and an old c2dm registration id works even after an uninstall and re-install.
any suggestions? how do others allow users to opt-out of notifications. how do you track their devices?
Having a Device ID is nice, but you don't need it to handle opt-outs. When you send a C2DM message from your server, include the registration ID. Then, when the device receives a message, it can compare the delivered registration ID with what it thinks its registration ID is.
If it matches, show the notification. If it doesn't match, ping your server and tell it to opt-out that registration ID.
On first run of your app, you could ask the user whether or not they would like to receive C2DM messages, and send that answer to your server. Then it follows that you would only send C2DM messages to devices that want them.
Instead of a GUID, I would look into getting their associated Android Market account (i.e. email address). This way, reinstalls won't change anything assuming they're using the same Android Market account.

Categories

Resources