Security and Privacy Changes in iOS 9
App Transport Security
This is a big one: by default on iOS 9, Apps will no longer be allowed to initiate plaintext HTTP connections, and will be required to use HTTPS with the strongest TLS configuration (TLS 1.2 and PFS cipher suites):
It is possible to lift these restrictions and still retrieve data over plaintext HTTP by adding some configuration keys to the App’s Info.plist.
Also, App Transport Security seems to only be available for connections initiated using
NSURLConnection is being deprecated (forcing everyone to switch to
NSURLSession for HTTP), I wonder if plaintext connections initiated through other network APIs (such as
NSStream) will fail as well.
A great change overall, and this might even be the first step to mandatory HTTPS as part of the App Store policy.
Detection of Installed Apps Blocked
Apple has closed three privacy gaps that allowed Apps to detect which other Apps were installed on the device.
The first technique was to use the
sysctl()function to retrieve the process table (a remnant of OS X), which includes the list of running Apps. In iOS 9,
sysctl()was modified to no longer allow sandboxed Apps to retrieve information about other running processes.
The second technique relied on the
UIApplication canOpenUrlmethod to try known URI schemes implemented by specific Apps, in order to detect if these Apps were installed on the device. This was made famous by Twitter, which used a list of 2500 URI schemes to detect which Apps were installed on the device. In iOS 9, Apps have to explicitly declare which schemes they would like to use in their Info.plist file. For Apps targeting iOS 8 but running on an iOS 9 device, there is also a hard limit of 50 URI schemes that can be checked at most.
There was a third technique which relied on the icon cache being accessible to sandboxed Apps. Although it wasn’t even mentionned in the WWDC video, this privacy leak has also been addressed in iOS 9.
Overall, closing these privacy gaps is a great move for users as these APIs were being abused by various Apps and analytics/ads SDKs.
Universal Links are meant to replace URI schemes for communicating with other Apps. In a nutshell, an App can specify a list of web domains they’re associated with:
Then, if the App is installed on the device, the App will have the ability to “receive” and open any HTTP or HTTPS link to the associated domains, when the link gets clicked on the device. If the App is not installed, the link will be opened in Safari instead.
This new mechanism is better than URI schemes for a few reasons:
- Strong ownership of links/content: enabling Universal Links requires uploading a specific file to the web domain to be associated with the App, which proves ownership. Conversely, a URI scheme could be claimed by any App that gets installed on the device.
- Because Universal Links rely on standard HTTP and HTTPS URLs, no need for specific, iOS-only URLs. Also, the links work regardless of whether the App is installed or not.
- Better privacy as Universal Links do not leak whether a specific App is installed on the device.
For more information, there’s a full WWDC session dedicated to Universal Links.
Mac Address Randomization Extended
Mac address randomization was introduced in iOS 8 in order to prevent the tracking of users through their device’s WiFi MAC address. This feature was initially criticized for being enabled only if location services were turned off on the device.
To further prevent user tracking, Apple has extended MAC address randomization to additional services, and seems to now include location services scans:
Misc. Keychain Improvements
Apple made some notable changes to the Keychain on iOS 9:
- The physical store where the Keychain cryptographic data is persisted has been moved to the Secure Enclave, the device’s cryptographic co-processor (available since the iPhone 5S).
- The weakest Keychain accessibility class,
kSecAttrAccessibleAlwayswill be deprecated in iOS 9. This protection class causes the data to not be encrypted at all when stored in the Keychain and has no real use case as
kSecAttrAccessibleAfterFirstUnlockcan always be used instead.
- When using TouchID to protect Keychain items,
touchIDAuthenticationAllowableReuseDurationcan be used to avoid re-prompting the user for their fingerprint if they already had a match some time ago.
Keychain items can now be encrypted using both the device’s passcode and an “Application password”; both values are then needed to decrypt and retrieve the item. This allows Apps to control when the data is accessible/decrypted, instead of having the data decrypted as soon as the device is unlocked. Potential use cases include:
- Allowing the user to configure an App-specific passcode to protect the user’s authentication token or encryption key; the App would then be able to prompt the user for their App passcode on launch.
- Storing the Application password on a server and having the App retrieve the password after a successful authentication.
- Having the Application password being displayed via a hardware token.
Application passwords can be configured using the LACredentialType.ApplicationPassword setting.
Secure Enclave Protected Private Keys
SecGenerateKeyPair(), which is used to generate RSA and ECDSA key pairs, can now be configured to directly store the generated private key in the device’s Keychain (within the Secure Enclave). The key can then be subsequently used to sign data or verify signatures directly within the Secure Enclave by specifying additional parameters to
SecKeyRawVerify(). This means that the private key can be used without ever leaving the device’s Secure Enclave. The
kSecAttrTokenIDSecureEnclave attribute needs to be used when generating the key pair.
Network Extension Points
Extensions were introduced in iOS 8, and are built around the concept of “extension points”: specific areas of the OS that can be customized using a designed API. Extension points from iOS 8 include for example “Custom Keyboard” and “Share”, respectively for customizing the device’s keyboard and adding new share buttons to receive content from other Apps. iOS 9 brings several new extension points geared toward network filtering and VPNs:
- The Packet Tunnel Provider extension point, to implement the client-side of a custom VPN tunneling protocol.
- The App Proxy Provider extension point, to implement the client-side of a custom transparent network proxy protocol.
- The Filter Data Provider and the Filter Control Provider extension points, to implement dynamic, on-device network content filtering.
These extension points can only be used with a special entitlement, thereby requiring Apple to approve the extension first.