Protecting Your Network Connections with ATS - Security - iOS 9 Swift Programming Cookbook (2015)

iOS 9 Swift Programming Cookbook (2015)

Chapter 11. Security

iOS 9 didn’t change much with regard to the Security framework. A few things were added, mainly about the keychain. There are also some additions that are about Application Transport Security, or ATS. ATS is now incorporated into iOS 9, so all apps compiled with Xcode 7, linked against iOS 9, and running under iOS 9 will by default use HTTPS for all their network traffic. This is really good, and not so good. It is good because it strongly encourages the use of secure connections for everything, but sometimes it can be annoying to force using a secure connection foreverything!

There are also some changes that affect the way we can store values in the keychain but overall, not much to worry about.

11.1 Protecting Your Network Connections with ATS

Problem

You want to control the details about the HTTPS channels through which your network connections go, or use a non-secure channel (HTTP).

I do not personally suggest using non-secure connections. However, in some cases, if you are using a backend that does not provide an HTTPS variant, you will be eventually forced to go through HTTP. In this chapter, I’ll help you figure out how to do that as well.

Solution

As I said, by default, all domain names that you use in your URLs will be going through secure channels. But you can indicate specific exceptions. ATS has a dictionary key in your Info.plist file called NSAppTransportSecurity. Under that, you have another dictionary key calledNSExceptionDomains. Under this key you can list specific domain names that don’t use ATS.

Discussion

If you want to disable ATS entirely so that all your network connections go through channels specified in your code, simply insert the NSAllowsArbitraryLoads key under the NSExceptionDomains key. The NSAllowsArbitraryLoads key accepts a Boolean value. If set to true, your HTTP connections will be HTTP and HTTPS will be HTTPS.

Alternatively, under the NSExceptionDomains key, you can specify the name of your domain and set its data type to be a dictionary. Under this dictionary, you can have the following keys:

NSExceptionAllowsInsecureHTTPLoads

If set to true, allows HTTP loads on the given domain.

NSIncludesSubdomains

If set to true, includes all the subdomains of the given domain as an exception from ATS.

NSRequiresCertificateTransparency

Dictates that the SSL certificate of the given URL has to include certificate-transparency information. Check certificate transparency out on the Web for more information.

NSExceptionMinimumTLSVersion

This is a key to which you assign a string value to specify the minimum TLS version for the connection. Values can be TLSv1.0, TLSv1.1, or TLSv1.2.

So if I want to disable ATS completely, my plist will look like this:

<plist version="1.0">

<dict>

<key>NSExceptionDomains</key>

<dict>

<key>NSAllowsArbitraryLoads</key>

<true/>

</dict>

</dict>

</plist>

How about if I want to have ATS enabled but not for mydomain.com? I’d also like to request certificate transparency and I’d like ATS to be disabled for subdomains as well:

<plist version="1.0">

<dict>

<key>NSExceptionDomains</key>

<dict>

<key>NSAllowsArbitraryLoads</key>

<false/>

<key>mydomain.com</key>

<dict>

<key>NSExceptionAllowsInsecureHTTPLoads</key>

<true/>

<key>NSIncludesSubdomains</key>

<true/>

<key>NSRequiresCertificateTransparency</key>

<true/>

</dict>

</dict>

</dict>

</plist>

How about if I want to enable ATS only for mydomain.com?

<plist version="1.0">

<dict>

<key>NSExceptionDomains</key>

<dict>

<key>NSAllowsArbitraryLoads</key>

<true/>

<key>mydomain.com</key>

<dict>

<key>NSExceptionAllowsInsecureHTTPLoads</key>

<false/>

<key>NSIncludesSubdomains</key>

<true/>

</dict>

</dict>

</dict>

</plist>

See Also