Skip to content

Instantly share code, notes, and snippets.

@vinhnx
Last active January 8, 2016 11:33
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save vinhnx/31ef407d68f45701c8f0 to your computer and use it in GitHub Desktop.
Save vinhnx/31ef407d68f45701c8f0 to your computer and use it in GitHub Desktop.
iOS 9 App Transport Security

iOS 9 App Transport Security

Starting from iOS 9, App Transport Security enforces to use secure HTTPS requests by default.

App Transport Security

App Transport Security (ATS) enforces best practices in the secure connections between an app and its back end. ATS prevents accidental disclosure, provides secure default behavior, and is easy to adopt; it is also on by default in iOS 9 and OS X v10.11. You should adopt ATS as soon as possible, regardless of whether you’re creating a new app or updating an existing one.

If you’re developing a new app, you should use HTTPS exclusively. If you have an existing app, you should use HTTPS as much as you can right now, and create a plan for migrating the rest of your app as soon as possible. In addition, your communication through higher-level APIs needs to be encrypted using TLS version 1.2 with forward secrecy. If you try to make a connection that doesn't follow this requirement, an error is thrown. If your app needs to make a request to an insecure domain, you have to specify this domain in your app's Info.plist file.

In short, when an application is compiled with Xcode 7 and iOS 9, and attempt to connect to HTTP server that doesn't support latest SSL technology (TLS 1.2), it will fail with an error like this:

CFNetwork SSLHandshake failed (-9801)
Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo=0x7fb080442170 {NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x7fb08043b380>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorCodeKey=-9802, NSUnderlyingError=0x7fb08055bc00 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1200.)", NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://yourserver.com, NSErrorFailingURLStringKey=https://yourserver.com, _kCFStreamErrorDomainKey=3}

From App Transport Security Technote:

All connections using the NSURLConnection, CFURL, or NSURLSession APIs use App Transport Security default behavior in apps built for iOS 9.0 or later, and OS X 10.11 or later. Connections that do not follow the requirements will fail. For more information on various the connection methods, see NSURLConnection Class Reference, CFURL Reference, or NSURLSession Class Reference.

Fortunately we can specify exceptions from default behavior in Info.plist. Doing this, we can leverage App Transport Security where possible, while disabling it in places where you cannot support it.

Per-Domain Exceptions

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>yourserver.com</key>
    <dict>
      <!--Include to allow subdomains-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--Include to allow HTTP requests-->
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!--Include to specify minimum TLS version-->
      <key>NSTemporaryExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

For arbitrary content

This is considerably a dangerous approach and should not be used sparingly.

<key>NSAppTransportSecurity</key>
<dict>
  <!--Include to allow all connections (DANGER)-->
  <key>NSAllowsArbitraryLoads</key>
      <true/>
</dict>

Some things to note:

  • Apps built using earlier SDK will behave the same. But if compiled using Xcode 7 onwards, we must migrate.
  • For apps using the Facebook SDK, read their guide to adapt changes.
  • For a short and more throughout information regarding this, you can read this article.
  • For full list of exception keys, check out this table from Apple.

References

Official documents:

Note from Facebook SDK and Google Ads SDK:

Articles and blogs:

@onmyway133
Copy link

A few notes that I observe

  • iOS 9 automatically translate "http" calls to "https" calls
  • If the server does not support "https" connection, an CFNetwork SSLHandshake failed error will occur, unless we specify to disable this "feature" in Info.plist
  • App built with iOS 9 SDK suffers from this "feature"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment