Skip to content

App Transport Security

Roger Hu edited this page Jun 5, 2017 · 19 revisions

Introduction

In iOS 9, Apple introduced "App Transport Security," or ATS. This defaults apps to requiring an HTTPS connection, and returning an error for non-HTTPS connections. In addition, HTTPS connections must also be using the latest protocol, Transport Layer Security (TLS) v1.2 and will fail to establish a connection if an older version is being used by the web server.

With modern web services, there is no reason to send data in the clear. Thanks to SSL session reuse, performance should no longer be a concern. All data should be sent over SSL.

These new defaults are useful for countering "leaks." While your may have moved all your REST API endpoints to HTTPS, they may reference insecure resources, such as image assets.

Overriding SSL Requirement

Unfortunately, you may have to connect to APIs outside of your control which do not offer HTTPS.

You can poke holes in ATS by adding a NSAppTransportSecurity dictionary to Info.plist. Add an NSExceptionDomains dictionary to whitelist specific domains. It may resemble:

  • NSAppTransportSecurity
    • NSExceptionDomains
      • api.rottentomatoes.com
        • NSExceptionAllowsInsecureHTTPLoads: YES

You may also use NSAllowsArbitraryLoads to completely disable ATS in your app:

Imgur

Or in XML:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key><true/>
</dict>

This is strongly discouraged. Only use this during development.

Testing

You can test out issues with App Transport Security by using the nscurl command:

nscurl --ats-diagnostics <URL>

The results will show you whether default connections will fail, and whether using using older versions of Transport Layer Security (TLS) or disabling options such as Perfect Forward Secrecy (PFS) will resolve the issue. For instance, you may need to modify Info.plist to include downgrading TLS versions or disabling PFS options:

<key>mywebsite.com</key>
<dict>
   <key>NSExceptionAllowsInsecureHTTPLoads</key>
   <false/>
   <key>NSTemporaryExceptionMinimumTLSVersion</key>
   <string>1.0</string>
   <key>NSTemporaryExceptionRequiresForwardSecrecy</key>
   <false/>
</dict>

Encryption Ciphers

ATS requires strict encryption ciphers. You can use the Chrome Security tab (View -> Developer -> Developer Tools) to check what encryption standard is used:

Make sure web sites must implement strong encryption ciphers that implement perfect forward secrecy. Here is the current list that iOS10 devices will support (in order of preference):

  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

If you are trying to test an internal site, the nmap tool can also be used to extract the encryption ciphers that a web site supports.

brew install nmap
nmap --script ssl-enum-ciphers -p 443 <URL>

In addition, there are public sites such as https://apptransport.info and ssllabs.com/ssltest/analyze.html that allow you to check whether public web sites are ATS-compatible. For apptransportinfo, Simply add the URL at the end (i.e. https://apptransport.info/www.codepath.com) to run the test.

Packet Traces

Troubleshooting ATS-related issues can be difficult to do. If you need to analyze the network traffic, you can follow Apple's guides to run packet traces using a tool such as Wireshark. You can use these tools to understand the TLS handshake.

First, connect an iPhone to the USB port of a Mac. Next, get the current list of interfaces:

$ ifconfig -l
lo0 gif0 stf0 en0 en1 p2p0 fw0 ppp0 utun0

Open iTunes on the Mac. Click on the icon for the iPhone device.

Click the Serial number text to display the UDID. Record the UDID by using Ctrl-Click to copy the UDID.

Then run the tool with the UDID of the device:

$ rvictl -s <UDID>

You should see: Starting device <UDID [SUCCEEDED]

Get the list of interfaces again, and you can see the new virtual network interface, rvi0, added by the previous command:

$ ifconfig -l
lo0 gif0 stf0 en0 en1 p2p0 fw0 ppp0 utun0 rvi0

You can then use WireShark to capture network traffic on the rvi0 interface.

Read More

Working with Apple's App Transport Security

If you need to troubleshoot, read Apple's docs for more information how to debug any SSL-related issues. Here are the technical docs for any specific error codes you may see in logs.

Clone this wiki locally