Back in March, a few users with Magisk installed noticed that their devices were failing SafetyNet attestation. This news was troubling to the community at XDA because it means that many crucial banking/financial apps and popular games like Pokémon Go and Fate/Grand Order were refusing to run on rooted devices. For some time, it seemed as if the tightened restrictions in SafetyNet were pulled back, only to roll out again for a handful of users in the last few weeks. However, Google quietly confirmed in early May that they testing hardware-backed attestation for SafetyNet responses, which is what made Magisk unable to hide the bootloader unlocking status back in March. If this change widely rolls out, it will mean that users will have to choose between having access to root/custom ROMs/kernels/etc. or their preferred banking apps and games. One of the biggest appeals of Android for power users could soon be gone.
To recap this series of events, we should first talk about SafetyNet itself. SafetyNet is a set of APIs in Google Play Services. The SafetyNet Attestation API is one of those APIs, and it can be called by third-party applications to check if the software environment of the device has been tampered with in any way. The API checks for various things like signs of superuser binaries, the bootloader unlock status, and more. When you root a device with Magisk, it “[creates] an isolated ‘safe environment’ for the [SafetyNet] detection process, and it goes through Google’s API to create a legit SafetyNet result that does not reflect the real status of the device,” per XDA Senior Recognized Developer topjohnwu. This allows the user to root their phone while ensuring that the API always returns “false” for any bootloader unlocking checks. This method of bypassing SafetyNet’s bootloader unlocking detection has been working out for Magisk for the last few years, but that’s only because Google has held off on verifying the integrity of the boot image using hardware attestation. In March, it seemed like Google was finally starting to employ hardware attestation in SafetyNet to verify the boot image, but we never got an official statement from Google confirming the change and only a few users were affected. As spotted by XDA Senior Member Displax, however, Google confirmed on May 5, 2020, that SafetyNet Attestation API responses from some devices now include hardware-backed checks.
On the Google Group for “SafetyNet API Clients,” Google detailed a new feature for the Attestation API: evaluationType. The JSON Web Signature (JWS) response from some devices will have a field named “evaluationType” that “will provide developers with insight into the types of signals/measurements that have contributed to each individual SafetyNet Attestation API response.” One of the supported tokens in this field is “HARDWARE_BACKED” which indicates that the API “[used] the available hardware-backed security features of the remote device (e.g. hardware-backed key attestation) to influence [its] evaluation.” Google says that they are “currently evaluating and adjusting the eligibility criteria for devices where we will rely on hardware-backed security features.” What this means is that, on some devices, Google Play Services is now using hardware-backed attestation to detect that the device’s software hasn’t been tampered with. Google has not officially documented this change outside of the announcement in the Google Group, so some developers that use SafetyNet may not be aware of this change (and thus aren’t yet checking for the “HARDWARE_BACKED” field in JWS responses.) However, for those apps that are checking for this field, there’s now no way to hide root access from them, provided your device is part of the test that Google is running.
According to topjohnwu, hardware-backed attestation means that Google Play Services now “[sends] an unmodified keystore certificate to SafetyNet servers, [verifies] its legitimacy, and [checks] certificate extension data to know whether your device [has] verified boot enabled (bootloader status).” Since the private keys from which the keystore certificates are derived from are backed by the phone’s isolated secure environment, retrieving them would involve defeating the security of the phone’s Trusted Execution Environment (TEE) or dedicated hardware security module (HSM). If one were somehow able to leak a private key, the keys would quickly be revoked once Google found out. Google and other companies offer hundreds of thousands of dollars in rewards for any critical security vulnerabilities in TEEs, so it’s incredibly unlikely for this to be a potential avenue to bypass bootloader unlocking detection anyways.
Another potential way that Magisk could continue to spoof the bootloader unlocking status is by modifying SafetyNet’s client-side code to always use the BASIC evaluation. As topjohnwu notes, though, this would require injecting custom code into Google Play Services via a hooking framework like the Xposed Framework. This is not only difficult to do because Google Play Services is highly obfuscated but it’s also impossible to hide as “some memory space analysis will reveal code manipulation very easily.” Furthermore, this would also only work if Google’s servers continue to accept BASIC evaluations and if HARDWARE_BACKED evaluations are not enforced on devices that support them. (SafetyNet responses “[come] from Google servers and are signed with Google’s private key,” according to topjohnwu, so the actual responses can’t be spoofed.)
Since Android 7 Nougat, Google has required that all devices have an isolated secure environment, meaning this change to how SafetyNet verifies bootloader unlocking will affect most devices that are out there. Since older devices without an isolated secure environment obviously can’t perform hardware-backed attestation, Magisk will still be able to hide root access on those devices. But if this change rolls out widely, everyone else will have to make a hard choice between root access and banking apps.
Unfortunately, there are probably a lot of apps out there that use SafetyNet checks when they don’t actually need to. One example cited by topjohnwu is the official McDonald’s app, which seemingly refuses to run on a bootloader unlocked device. On Twitter, topjohnwu calls out apps that overuse the API as creating a hostile environment for power users. XDA Recognized Developer Quinny899 joins in with an anecdote about how his team considered using SafetyNet to check the device security status. They ultimately decided not to go through with it since his team’s app encrypts all the sensitive data it works with. SafetyNet, he argues, should not be used in lieu of proper security and data handling practices, especially when considering the possibility of superuser exploits.
I advocate @AndroidDev to restrict hardware-backed SafetyNet evaluation to “real” security sensitive apps. Developers should go through an application process to qualify this level of API access. It is ridiculous for McDonalds to refuse to run on a bootloader unlocked device.
— John Wu (@topjohnwu) June 29, 2020
For more information on how the new SafetyNet change affects Magisk, check out topjohnwu’s excellent FAQ on Twitter. If you just want to check if your device is part of Google’s new SafetyNet test, then you can follow this guide by XDA Senior Member Displax.