Can android sign a http/https call, to identify uniquely the app doing the request?

1.9k views Asked by At

Say, CORS for apps. Well, not the same thing, but...

Supposse I have uploaded an app to play store, and now I want my server to accept only connections from this app.

How can I do it?

What I would expect of the OS is is some process such as adding to my http request a couple of headers specifying the id of the app in the market, and signing the whole request with a signature in the android chain -or in the corresponding market CA certificate chain-. Then my server could verify that the request comes from the right app.

Plus, the OS could add some certified hardware info so if the app is run in an emulator I could deny service too.

Another way could be to include a "secret" in the app, of course, but it could always be reverse-engineered by decompilation, couldn't it? Or is there some keystore associated to the play store that could be used to provide this secret during https requests to the server?

A third way could be to use the azp field of an OAuth login, but again it could be compromised by decompilation, and moreover it forces the user to log in.

2

There are 2 answers

0
arivero On

Use the Safety Net Attestation flow to request a secret token to the server.

After reading related questions, I think the trick is to use the Safety Net flow:

  • using the SafetyNet Attestation API the app gets a signed json from android services.
  • the app generates some id from android_id, random uuid or both.
  • Both Id and json are sent to the server which can then verify that the request comes from the real app, save the id and config data, and agree a token for further communications.
  • using the keychain api, the app saves the id and token in the keystore for future usage

This is an speculative answer (I am the OP), please upvote it only if you are sure it is correct and a better alternative is not listed.

Attestation Flow, from Android documentation

0
Exadra37 On

Supposse I have uploaded an app to play store, and now I want my server to accept only connections from this app.

How can I do it?

To achieve the best level of security between your App and the API server you should use a Mobile App Attestation service alongside the SafetyNet solution, plus an OAUTH2 service and finally certificate pinning to secure the communication channel between the API server and the Mobile App, as covered in this series of articles about Mobile API Techniques.

The role of a Mobile App Attestation service is to guarantee at run-time that your App was not tampered or is not running in a rooted device by using an SDK integrated in your App and a service running in the cloud.

On successful attestation of the App Integrity a JWT token is issued and signed with a secret that only the API server of your App and the Mobile App Attestation service in the cloud are aware.

In the case of failure on the App Attestation the JWT is signed with a secret that the API server does not know.

Now the App must sent with every API call the JWT token in the headers of the request. This will allow the API server to only serve requests when it can verify the signature in the JWT token and refuse them when it fails the verification.

Once the secret used by the Mobile App Attestation service is not known by the App, is not possible to reverse engineer it at run-time even when the App is tampered, running in a rooted device or communicating over a connection that is being the target of a Man in the Middle Attack. This is where this type of service shines in relation to the SafetyNet solution.

As a side note if your App talks directly with third parts services, then I suggest that you delegate that responsibility to the API server, that will prevent unauthorized use of your third part services in your behalf, once it only serves now authentic requests from the Mobile App's that passed the Integrity challenges.

So why not use only SafetyNet? Despite being a good security feature added to Android it was not designed to be used as the sole security defence of your app, as per Google own words:

The goal of this API is to provide you with confidence about the integrity of a device running your app. You can then obtain additional signals using the standard Android APIs. You should use the SafetyNet Attestation API as an additional in-depth defense signal as part of an anti-abuse system, not as the sole anti-abuse signal for your app.

Before I go I would like to call the attention for the following in the SafetyNet solution:

  • It is part of Google Mobile Services (GMS) so only runs on devices that have this. In some markets, such as the far east, there are a significant number of devices that do not have this available.

  • There are a limited number of attestation calls that can be made with a standard free API key, so to use at scale a (presumably) paid level would be required.

  • It is primarily designed to check if the OS image that a particular Android device is running is considered to be secure and compatible or not. As such it can be considered to be quite advanced root check that is able to check for file system changes indicative of rooted devices.

  • Since the SafetyNet is doing a full analysis of the hashes of the OS image it can actually be quite slow (sometimes a few seconds). This means that it cannot be doing continuously and some care is needed in its use to hide this latency from the user, but without creating an opening for an attacker to exploit.

  • SafetyNet does not specifically analyse the memory map of running apps to detect instrumentation frameworks (it relies on the fact that they can only run on rooted devices), like XPosed and Frida.

  • SafetyNet does provide an attestation of the running app via the apkDigestSha256 feature. However, this can only be relied upon if full integrity is reported. This means that the integrity of the app is unknown if it is running on any kind of unusual or rooted devices. Some users root their devices only for customizations purposes and if the mobile app has a significant percentage of them then SafetyNet will exclude them from being able to use the app. In this scenarios we want to know specifically about the integrity of the running app rather then the system as a whole. SafetyNet is not able to do that, but a mobile app attestation service can.

  • In order to perform the attestation check in a way that cannot be spoofed then app cannot do its own check (as obviously this code could be tampered with itself). Thus there is a need to implement a server side to use the feature reliably.