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.