Both iOS and Android provide built-in device-level checks which can help prevent mobile application abuse. On iOS, DeviceCheck provides a way to associate a few pieces of information per app with each device, On Android, SafetyNet device attestation attempts to ensure that a device is running in a safe environment. These are useful capabilities, but they are only a small part of an in-depth mobile app and API protection scheme.
For almost all useful apps today, interaction with remote services through APIs is the major mode of operation. While security concerns often seem to focus on user authentication, all possible attack surfaces must be considered to ensure a secure API transaction.
From the perspective of the API service, all API calls must be protected by a secure channel between app and service. Although TLS encrypts the channel, a clever attacker may compromise certificate authority on the device or network, so certificate pinning, which can be difficult to implement and maintain, should be used to protect against man-in-the-middle attacks.
Secondly, the API service must have confidence that the app running on the device is authentic. All fake or tampered apps must be rejected. The most common form of app authentication when making an API call is the venerable (and vulnerable) static API key. No matter how well hidden, if hacking the API service is valuable enough, the API key will be stolen, either by reverse engineering in the app or by observing it in an unpinned channel.
Reliable tamper-detection techniques are a must, and decisions about the authenticity of an app should always be made outside the app itself in case the checks themselves are tampered with or bypassed. Remote mobile app attestation techniques can protect against both fake and tampered apps. The app’s package, installed code, and the run time environment are all potential attack surfaces for tampering.
If you have a secure channel and an authentic app, it’s finally time to worry about properly authenticating and authorizing the user using protocols like OAuth2 and OIDC combined with biometric and/or multi-factor authentication. But don’t forget, user authentication is only as strong as the other factors. Standard OAuth2, for example, uses a secret for app authentication, and that’s not enough to prevent a fake app from stealing user credential info.
DeviceCheck provides developers a reliable way to identify a device and can store two bits of information about the device per app. The flags are maintained even if the app is deleted and reinstalled, a user logs in with different credentials or a system reset is performed. Typical flags might include ‘Has this device ever been compromised?’ or ‘Has this app’s free promotion period been used for this device?’.
The DeviceCheck API generates an ephemeral token which uniquely identifies the device to Apple. Your API service combines this token with an authentication key from Apple and requests or updates the flags identified by the per-device bits and maintains a timestamp indicating when they were last modified.
The DeviceCheck implementation assures users of their privacy even while uniquely identifying the device. Developers receive only an ephemeral token, rather than a device serial number or any other identifying information. Similarly Apple stores the flags and timestamps but has no idea of how the flags are interpreted.
From an app authentication perspective, the flags could be used to identify compromised devices or apps, but it is still up to the developer to determine the app’s authenticity. Since app and device conditions change frequently, the ability to store the last authenticity check is of only marginal value.
DeviceCheck and Approov provides more information on how DeviceCheck compares with a state of the art app authentication system.
On Android, SafetyNet is installed as part of Google Play Services installed on Google-approved Android devices. It consists of four APIs:
(Source: Inside Android SafetyNet Attestation)
When using the device attestation API, an app makes a call to the device attestor which sends run time measurements to Google Play Services. Google evaluates the information and provides a cryptographically secure assessment back to the app. The app then forwards the assessment on to the API service for validation. The assessment decision is made outside the app, which is good practice, and the assessment decision can be used by the app to, for example, shut down a mobile-banking app if it is running on a rooted or non-standard phone setup.
Apps must be constantly evaluating not just device health but the health of the application itself. SafetyNet provides limited but effective run-time checks; however, most apps will need additional, more app-specific checks. SafetyNet provides some protection against Fake or tampered apps by reporting the application signature, but full app attestation provides far more protection against zero-day and more dynamic exploits. Note also that access to Google Play Services is required to use SafetyNet.
SafetyNet and Approov provides more information on how SafetyNet compares with a state of the art app authentication system.
DeviceCheck and SafetyNet are potentially useful parts of a mobile API defense in depth security approach. DeviceCheck enables you to mark your app or device as untrusted if you can detect that by some other means. SafetyNet provides more structured checks of the device’s run time environment. Both services can augment but are no replacement for solid app attestation techniques.
For a more in-depth look at mobile API focused security, take a look at the Preventing Mobile App and API Abuse presentation from OWASP AppSec California 2019.
Thanks for reading! For more information on mobile API security, check out www.approov.io.