Since the release of iOS 8, the Touch ID fingerprint sensor can now also be used in third-party apps. The Local Authentication framework provides an API via which users can conveniently deploy their biometric fingerprint to authenticate themselves in both apps from the App Store and enterprise apps. In the medium term, we anticipate that more and more apps will switch to the fingerprint method of user authentication. After all, it’s much easier to place your finger on a sensor than it is to enter a 10-digit alphanumeric password — and the additional biometric verification gives users a very good sense of security. The problem is that this feeling of security is extremely deceptive.
Local Authentication Backgrounds
Merely glancing at the sample code provided by Apple makes it immediately apparent that Local Authentication, as the name states, is purely a client-side security measure. And, as we have come to realise, client-side measures are recommended only with caveats. Ultimately, when Local Authentication is used, the method evaluatePolicy:localizedReason:reply: returns to the app in the reply block, whether or not the fingerprint authentication was successful. Depending on the status of the Boolean variable, developers can then display an error message or, in successful cases, e.g., hide the frontmost login screen.
Since I first heard about this new framework, I have questioned its usefulness. Ultimately, Local Authentication becomes only important when an unlocked device falls into the wrong hands. Than Local Authentication is designed to ensure that, when an app is launched, an additional login screen is displayed to prevent access to the app’s contents. However, in this very moment it is still possible, e.g., to directly access all app data via the USB interface (for example, by creating a backup). After all, the device is already unlocked (otherwise you wouldn’t need Local Authentication).
In order to prevent the latter scenario, sensitive information is usually encrypted using an additional, app-level encryption. The key required to decrypt the information is then derived from the password entered when the app is launched. Touch ID means, however, that no password is entered and the Secure Enclave coprocessor returns only a thumbs-up or thumbs-down. There is, therefore, no password from which to derive a key. As authentication without additional encryption makes little sense when storing sensitive data locally, the Local Authentication concept should, therefore, be called into question. It may, for example, be sufficient to prevent children playing with the device from promptly accessing sensitive app data, but the Local Authentication provided in the sample code from Apple provides no actual security benefit.
I found it also somewhat surprising that, in WWDC 2014 Session 711 (Keychain and Authentication with Touch ID), Apple specifies possible uses for Local Authentication that involve Touch ID potentially replacing passwords or PINs, or even Touch ID being used as a second factor. As I aim to show in the following example, I find this questionable. Enterprise apps, in particular, would do better to avoid this form of authentication.
A Real-Life Example: Dropbox App
When searching the App Store for apps that already provide Local Authentication, I came across the Dropbox App. Just a few days ago, the integration of Touch ID into the Dropbox App was highly praised in the media. CNET quotes include: “Dropbox users with sensitive documents stored on their iPhone or iPad can now protect them with a simple fingerprint” and “the measure throws in an extra layer of app-specific protection to your files”.
In order to use Touch ID in the Dropbox App, users must first set their own passcode in the app settings. The app then displays a login screen each time it launches. At first glance, this seems nice and secure.
It is notable that the passcode comprises just four numbers. This alone makes it vulnerable to brute force attacks. Later, however, it turned out that it doesn’t actually matter, as the passcode is not used to encrypt the locally stored Dropbox files. Instead, the passcode is simply stored in the keychain. When the app is launched the next time and the PIN is entered, the app checks whether or not the value entered matches the value stored in the keychain. If it does, the method passcodeViewControllerDidReceiveCorrectPasscode from class DBLoggedInPasscodeState is used to dismiss the passcode view. The same method is called if, following authentication using Touch ID, the Local Authentication framework returns success in the reply block.
Users who want to try hiding the login screen without knowing the passcode can simply use the following Cycript Code:
// Dropbox for iPad var PasscodeViewController = [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController->_passcodeController; // Dropbox for iPhone var PasscodeViewController = [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController; var DBLoggedInPasscodeState = [DBStateManager sharedInstance]->_dbState; [DBLoggedInPasscodeState passcodeViewControllerDidReceiveCorrectPasscode:PasscodeViewController];
This hides the login screen and permits access to all Dropbox files. To avoid confusion, I’d like to emphasise that proving this concept using Cycript requires a jailbroken device! This attack cannot be carried out as described on non-jailbroken devices. Instead of changes being made using Cycript at runtime, the app binary would, for example, need to be modified and the passcode check directly deactivated within it. This would also be possible on non-jailbroken devices. Moreover, I'd like to emphasise that I'm not criticizing Touch ID in general, but its use in third-party apps.
To return to the topic at hand, however, it is important to realise that the authentication in Dropbox, and Local Authentication in general, lulls users into a false sense of security. As the Dropbox files are not protected by app-level encryption in addition to Apple’s file Data Protection, the files could, for example, still be read via the USB interface. This requires that the device in question be unlocked — but, as mentioned earlier, Local Authentication becomes relevant only in such scenarios. The bottom line is that Local Authentication can be used if your threat model includes your kids or spouse, but not to protect yourself against any serious adversary.
When it comes to Dropbox, I would like to see the following improvements:
- The option to set a complex alphanumeric password instead of just a 4 digit passcode
- Additional, app-level encryption of files based on the user passcode entered
- Encryption of downloaded files using the NSFileProtectionComplete class key (instead of iOS default’s NSFileProtectionCompleteUntilFirstUserAuthentication).
If Touch ID authentication is to be continued, perhaps it would be worth taking a look at the keychain access control lists (ACL), a new concept that was introduced in iOS 8. The attribute kSecAttrAccessControl can be used to define that keychain entries can be decrypted only if the user has again been authenticated using the device passcode or Touch ID (kSecAccessControlUserPresence). In such cases, the Touch ID login would be more than just a worthless view. Instead, it could actually grant access to cryptographic keys. As, however, the keys would still be stored on the device (although in the keychain), this is merely a compromise, albeit one which could actually provide added value (ACL protected items are not backed up). From a security perspective, however, entering a password is still recommended.