App Transport Security


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
        • NSExceptionAllowsInsecureHTTPLoads: YES

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


Or in XML:


This is strongly discouraged. Only use this during development.


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:


Read More

Working with Apple's App Transport Security

Fork me on GitHub