/ ios

Brace yourselves: ATS is coming

Application Transport Security

Since HTTP is a plaintext protocol and therefore creates inherent security and privacy concerns when used by applications - Apple has decided that it is finally time to start treating the secure alternative, HTTPS, as the de facto web protocol for iOS mobile apps. At WWDC this year, Apple rightly pointed out that simply "enabling" HTTPS does not necessarily mean that you are secure. There are many ways in which HTTPS can be improperly configured resulting in the use of insecure connections.

App Transport Security (ATS) was introduced by Apple in iOS 9 as a built in utility for protecting network communications. Out of the box, ATS enforces a TLS configuration with the following criteria:

  • Apps can only connect to servers using the TLS 1.2 protocol
  • Apps can only connect to servers which provide strong ciphers.
    • Strong ciphers are described as AES128+ and SHA2+
  • Apps must connect to servers using Perfect Forward Secrecy (PFS) however Apple has stated that they'll allow exceptions for this (for now).

Disabling ATS

We have tested a lot of iOS9 apps at Cigital and so far we've observed that developers tend to disable ATS completely (via the Info.plist, using "Allowing Arbitrary Loads"). Although this is currently acceptable as far as Apple is concerned, they have announced a date at which they will no longer allow applications to do this - end of year 2016.

Enforcement is coming

Applications will be expected to use ATS by the end of year 2016 or consequently are required to provide a valid reason as to why an exception should be granted - where such acceptance will be at Apple's discretion during App Store review. It is therefore recommended to start planning for this now, if you have not already.

Engineering teams should start working with architectural and infrastructure teams immediately to discuss how and when to implement secure server side TLS configuration.

Diagnosing connectivity problems

Once you have enabled server side TLS, you can check your configuration and identify compatibility issues easily using nscurl on an OSX/macOS system. For example, using hexplo.it as the target domain:

nscurl --ats-diagnostics https://hexplo.it

This returns the following output:

Starting ATS Diagnostics

Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://hexplo.it.
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
Use '--verbose' to view the ATS dictionaries used and to display the error received in URLSession:task:didCompleteWithError:.
================================================================================

Default ATS Secure Connection
---
ATS Default Connection
Result : PASS
---

================================================================================

Allowing Arbitrary Loads

---
Allow All Loads
Result : PASS
---

================================================================================

Configuring TLS exceptions for hexplo.it

---
TLSv1.2
Result : PASS
---

---
TLSv1.1
Result : PASS
---

---
TLSv1.0
Result : PASS
---

================================================================================

Configuring PFS exceptions for hexplo.it

---
Disabling Perfect Forward Secrecy
Result : PASS
---

================================================================================

Configuring PFS exceptions and allowing insecure HTTP for hexplo.it

---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled for hexplo.it

---
TLSv1.2 with PFS disabled
Result : PASS
---

---
TLSv1.1 with PFS disabled
Result : PASS
---

---
TLSv1.0 with PFS disabled
Result : PASS
---

================================================================================

Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for hexplo.it

---
TLSv1.2 with PFS disabled and insecure HTTP allowed
Result : PASS
---

---
TLSv1.1 with PFS disabled and insecure HTTP allowed
Result : PASS
---

---
TLSv1.0 with PFS disabled and insecure HTTP allowed
Result : PASS
---

================================================================================

In this instance, the key output is the following:

Default ATS Secure Connection
---
ATS Default Connection
Result : PASS
---

The above output shows that the server supports the default ATS connection and thus ATS will work out of the box for this host; subsequently your application will now be able to communicate to this host securely - without disabling ATS. If the output says FAIL, then something is misconfigured and the issue will need to be diagnosed.

Alternatively, developers can set the CFNETWORK_DIAGNOSTICS environment variable to 1 within the Xcode project, to capture networking based debug logging which too can help diagnose ATS connection issues.

What if I can't enable strong TLS right now?

There are numerous available exception types within ATS, most of which have legitimate use cases. Examples are explained below:

  • NSAllowArbitraryLoads - Straight up disables ATS policy enforcement. This allows apps to connect via insecure HTTPS channels and also via HTTP.
  • NSExceptionAllowsInsecureHTTPLoads - allows connections to this domain via the HTTP protocol.
  • NSExceptionMinimumTLSVersion - Lowers the TLS minimum version required from 1.2 to the value declared.
  • NSExceptionRequiresForwardSecrecy - Disables the requirement for PFS.
  • NSAllowsArbitraryLoadsInMedia - for streaming remote media via AVFoundation Note this was not available until iOS 10.
  • NSAllowsArbitraryLoadsInWebContent - for accessing and displaying web content through WKWebView objects. Note this was not available until iOS 10.
  • NSThirdPartyExceptionAllowsInsecureHTTPLoads - see above, but for third party domains.
  • NSThirdPartyExceptionRequiresForwardSecrecy - see above, but for third party domains.
  • NSThirdPartyExceptionMinimumTLSVersion - see above, but for third party domains.

What about domains I don't own?

A lot of applications are found to communicate with other 3rd party domains as well as the domains under the same ownership as the application itself. In this scenario, we can disable ATS for a specific domain, declaring also that it is a 3rd party domain.

This can be achieved as shown below:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>hexplo.it</key>
        <dict>
            <key> NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

In the above, we have set NSThirdPartyExceptionAllowsInsecureHTTPLoads to true, allowing HTTP connections for the hexplo.it host.

It is of course advisable to speak to your 3rd party vendors and ask them to upgrade their infrastructure to support ATS where possible. Of course, as stated above, exceptions will have to be justified to Apple during App Store review, please bare this in mind.

Summary

To summarise, App Transport Security enforcement is looming. It is advisable to start planning support for ATS now, so as to make the deadline. Don't panic if you are finding that you ultimately cannot enable ATS globally, there are exceptions for a reason and Apple has said they will listen to your justifications during review. However, you should plan your release dates accordingly to compensate for any pushback from Apple. Where possible, you should strive to comply with ATS configuration rather than rely on exceptions. This not only avoids unnecessary delays when going live but provides greater security to the app and users.