Security and Privacy Changes in iOS 12
This year and for the first time, I actually went to the Apple WWDC conference, in San Jose. The conference was quite interesting, and gave me the opportunity to meet some of the members of the Apple security team.
Here are some notes about the security and privacy changes brought by iOS 12 that I thought were interesting.
Automatic strong passwords
The “Automatic Strong Passwords and Security Code AutoFill” session describes various enhancements made to the iOS built-in password management functionality.
Automated password generation
Starting with iOS 11, developers can “label” the username and password field in their app’s login screen:
let userTextField = UITextField()
userTextField.textContentType = .username
let passwordTextField = UITextField()
passwordTextField.textContentType = .password
This allows iOS to automatically login the user with the credentials they previously saved in their iCloud account, if the app has been properly associated with its web domains.
With iOS 12, a strong password can automatically be generated and stored when creating a new account in an app or in Safari. This functionality can be enabled by using the .username
and the iOS 12 .newPassword
content types in your “Create Account” screen:
let userTextField = UITextField()
userTextField.textContentType = .username
let newPasswordTextField = UITextField()
newPasswordTextField.textContentType = .newPassword
let confirmNewPasswordTextField = UITextField()
confirmNewPasswordTextField.textContentType = .newPassword
iOS 12 will then prompt the user to automatically generate a strong password during the account creation flow.
Any password that was automatically generated will contain upper-case, digits, hyphen, and lower-case characters. If your backend has limitations in the characters it allows in passwords, you can define a custom password rule in your app via the UITextInputPasswordRules
API:
let newPasswordTextField = UITextField()
...
let rulesDescriptor = "allowed: upper, lower, digit; required: [$];"
newPasswordTextField.passwordRules = UITextInputPasswordRules(descriptor: rulesDescriptor)
Apple has also released an online tool to help with writing password rules.
Similar labels can be used in a web page that Safari can leverage:
Automated 2FA SMS codes input
iOS 12 also introduces a content type for the text field that will receive 2 factor authentication codes received via SMS:
let securityCodeTextField = UITextField()
securityCodeTextField.textContentType = .oneTimeCode
Enabling this content type allows iOS to automatically fill in a 2FA code previously received via SMS (with a user prompt), which is pretty cool:
Federated authentication
iOS 12 introduces a new ASWebAuthenticationSession
API for automatically handling an OAuth login flow.
Given an OAuth URL (ie. where to start the authentication flow), the API will:
- Direct the user to the OAuth provider’s authentication page.
- Have the user then log into their account on the provider’s page. As the API uses the same cookie store as Safari, the user may already be logged into their account; if that’s the case, the user will be prompted to confirm that they want to re-use their existing session in Safari, making the flow really quick.
- Allow the user to review the OAuth permissions requested by your app, and grant access via the OAuth authorization prompt.
- Return the user to your app and provide the callback URL, which contains the user’s authentication token if the flow was successful.
It was stated during the WWDC presentation that ASWebAuthenticationSession
is now the “go-to way to implement federated authentication and it replaces SFAuthenticationSession
”, which was deprecated in iOS 12.
Credential Provider Extension
All the password management improvements described above apply to the built-in password manager in iOS and Safari, the “iCloud KeyChain”. However, third-party password manager applications (such as LastPass, 1Password, etc.) can also get integrated into the password flows on iOS, via a new extension point called “Credential Provider Extension”.
This extension point and the corresponding APIs are all part of the new AuthenticationServices
framework available on iOS 12. This framework allows providing a UI for user to choose their password when authenticating into an app, storing a newly-created password, etc.
The framework is described in details in the “Implementing AutoFill Credential Provider Extensions” presentation.
Secure object de-serialization
At WWDC this year, a whole presentation was dedicated to secure object serialization and de-serialization: “Data You Can Trust”.
When an application has some logic to receive arbitrary data (for example over the Internet) and to then de-serialize the data into an object, care must be taken when implementing this logic. Specifically, if the raw data can choose any arbitrary class as the the object it gets de-serialized to, this can lead to remote code execution. This type of vulnerability affects almost every language and framework, for example Apache and Java, Ruby on Rails, or Python’s pickle module.
In iOS applications, object (de-)serialization is usually implemented using:
- The
NSCoding
protocol, which allows the developer to implement the serialization logic for their own classes. - The
NSKeyedArchiver
class which takes an object that implementsNSCoding
and serializes it into a specific file format called an archive, which can then be stored for example on the file system. TheNSKeyedUnarchiver
class can then be used to de-serialize the object.
This approach is vulnerable to the issue described above, referred to as an “object substitution attack” in the Apple documentation: the data gets de-serialized to a different object than what was expected by the developer.
To prevent such attacks, the following APIs were introduced in iOS 6:
[NSKeyedArchiver decodeObjectOfClass:forKey:]
, which allows the developer to pick the class the data will get de-serialized to before it occurs, thereby preventing object substitution attacks.- The
NSSecureCoding
protocol which extends theNSCoding
protocol by adding the class methodsupportsSecureCoding:
, in order to ensure that the developer is using the safe-decodeObjectOfClass:forKey:
method to handle object serialization and de-serialization in their classes.
The “Data You Can Trust” presentation this year heavily emphasized NSSecureCoding
and -decodeObjectOfClass:forKey:
:
What has changed with iOS 12 is that [NSKeyedArchiver init]
constructor is now deprecated; this was done to get developers to switch to the [NSKeyedArchiver initRequiringSecureCoding:]
constructor instead, which has been made public on iOS 12 (but seems to be retro-actively available in the iOS 11 SDK). This constructor creates an NSKeyedArchiver
that can only serialize classes that conform to the NSSecureCoding
protocol, ie. objects that are safe to serialize and de-serialize.
The Network framework
The Network framework, introduced somewhere around iOS 9 or 10 has become a public API on iOS 12.
It is a modern implementation of a low-level networking/socket API. As stated in the documentation, it is meant to replace all the other low-level networking APIs available on iOS: BSD sockets, SecureTransport and CFNetwork:
“Use this framework when you need direct access to protocols like TLS, TCP, and UDP for your custom application protocols. Continue to use NSURLSession, which is built upon this framework, for loading HTTP- and URL-based resources.”
More details about the Network framework are available in the “Introducing Network.framework: A modern alternative to Sockets” presentation.
Developers should expect the legacy network APIs (SecureTransport, etc.) to eventually get deprecated by Apple. Right now and as mentioned in the presentation, they are “discouraged APIs”.
The Network framework also comes with its own set of symbols for handling TLS connections, such as certificates, identities, and trust objects. They mirror the legacy SecureTransport symbols and can be used interchangeably. For example, a SecCertificateRef
, which represents an X.509 certificate, is a sec_certificate_t
in the Network framework. The sec_certificate_create()
function can be used to turn a SecCertificateRef
into a sec_certificate_t
.
Lastly, App Transport Security is not enabled for connections using the Network framework, but will be “soon” according to Apple engineers.
Other changes
Deprecation of UIWebView
Starting with iOS 12, the UIWebView API
is now officially deprecated. Developers that need web view functionality in their application should switch to the WKWebView API
, which is a massive improvement over UIWebView
in every aspect (security, performance, ease of use, etc.).
Unified Random Number Generation in Swift 4.2
Swift 4.2 introduces an API for generating random number, described in the “Random Unification” proposal.
Previously, generating random numbers in Swift was done by importing C functions that are insecure in most cases (such as arc4random()
).
Enforcement of Certificate Transparency
Apple will be enforcing Certificate Transparency at the end of 2018 across all TLS connections on iOS. This does not require any changes in your application as the work to deploy CT has been carried out by the Certificate Authorities. More details are available in the “Certificate Transparency policy” article.
The CT enforcement will be deployed “with a software update later this year”.
Enforcement of App Transport Security
With iOS 9, Apple introduced App Transport Security (ATS), a security feature which by default requires all of an app’s connections to be encrypted using SSL/TLS. When ATS was first announced, it was going to be mandatory for any app going through the App Store Review process, starting on January 1st 2017. Apple later cancelled the deadline, and no further announcements about requiring ATS have been made.
However, at WWDC this year, I learned that Apple has started reaching out to specific apps through the App Store review process, in order to ask for justifications and/or require the applications’ ATS policy to be stricter, especially having NSAllowsArbitraryLoads
(the exemption that fully disables ATS) set to NO
.
So what should I do?
If you are a developer, here is a summary of the changes to implement in your application, based on all the iOS 12 features described in this article.
Short term
- Add support for Password Autofill to your application. The “Enabling Password AutoFill on a Text Input View” article gives a good summary of the changes you need to implement in your app.
- If your application’s ATS policy still sets
NSAllowsArbitraryLoads
toYES
, modify your policy by adding the required exemptions and domains, in order to be able to setNSAllowsArbitraryLoads
toNO
. More details on how to achieve this are available in our ATS guide. Sooner or later, your application will get blocked if it enablesNSAllowsArbitraryLoads
.
Medium term
- If your application is using
NSCoding
for object serialization, switch toNSSecureCoding
in order to prevent object substitution attacks. - If you application is using the now-deprecated
UIWebView
API, switch toWKWebView
.
Long term
- If your application is using a low-level network API (such as BSD sockets, SecureTransport or CFNetwork) switch to the
Network
framework.