How do I load an HTTP URL with App Transport Security enabled in iOS 9?

420,422

Solution 1

See Apple’s Info.plist reference for full details (thanks @gnasher729).

You can add exceptions for specific domains in your Info.plist:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>testdomain.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSThirdPartyExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSRequiresCertificateTransparency</key>
            <false/>
        </dict>
    </dict>
</dict>

All the keys for each excepted domain are optional. The speaker did not elaborate on any of the keys, but I think they’re all reasonably obvious.

(Source: WWDC 2015 session 703, “Privacy and Your App”, 30:18)

You can also ignore all app transport security restrictions with a single key, if your app has a good reason to do so:

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

If your app does not have a good reason, you may risk rejection:

Setting NSAllowsArbitraryLoads to true will allow it to work, but Apple was very clear in that they intend to reject apps who use this flag without a specific reason. The main reason to use NSAllowsArbitraryLoads I can think of would be user created content (link sharing, custom web browser, etc). And in this case, Apple still expects you to include exceptions that enforce the ATS for the URLs you are in control of.

If you do need access to specific URLs that are not served over TLS 1.2, you need to write specific exceptions for those domains, not use NSAllowsArbitraryLoads set to yes. You can find more info in the NSURLSesssion WWDC session.

Please be careful in sharing the NSAllowsArbitraryLoads solution. It is not the recommended fix from Apple.

kcharwood (thanks @marco-tolman)

Solution 2

As accepted answer has provided required info, and for more info about using and disabling App Transport Security one can find more on this.

For Per-Domain Exceptions add these to the Info.plist:

<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>

But What If I Don’t Know All the Insecure Domains I Need to Use? Use following key in your Info.plist

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

For more detail you can get from this link.

Solution 3

Followed this.

I have solved it with adding some key in info.plist. The steps I followed are:

  1. Opened my Projects info.plist file

  2. Added a Key called NSAppTransportSecurity as a Dictionary.

  3. Added a Subkey called NSAllowsArbitraryLoads as Boolean and set its value to YES as like following image. enter image description here

Clean the Project and Now Everything is Running fine as like before.

Ref Link.

Solution 4

If you just want to disable App Transport Policy for local dev servers then the following solutions work well. It's useful when you're unable, or it's impractical, to set up HTTPS (e.g. when using the Google App Engine dev server).

As others have said though, ATP should definitely not be turned off for production apps.

1) Use a different plist for Debug

Copy your Plist file and NSAllowsArbitraryLoads. Use this Plist for debugging.

XCode Debug

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

2) Exclude local servers

Alternatively, you can use a single plist file and exclude specific servers. However, it doesn't look like you can exclude IP 4 addresses so you might need to use the server name instead (found in System Preferences -> Sharing, or configured in your local DNS).

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>server.local</key>
        <dict/>
        <key>NSExceptionAllowsInsecureHTTPLoads</key>
        <true/>
    </dict>
</dict>

Solution 5

I have solved as plist file.

  1. Add a NSAppTransportSecurity : Dictionary.
  2. Add Subkey named " NSAllowsArbitraryLoads " as Boolean : YES

enter image description here

Share:
420,422
Graeme Mathieson
Author by

Graeme Mathieson

Yet another Ruby on Rails software developer, who lives in Devon, and is awesome.

Updated on July 29, 2022

Comments

  • Graeme Mathieson
    Graeme Mathieson almost 2 years

    So, the new beta SDK of iOS released last night has "App Transport Security" which encourages developers to use https instead of http. In principle, this is a great idea, and I already use https in our staging/production environments. However, I don't have https set up in my local development environment, when the iOS app is connecting to a web service I'm running on my laptop.

    From a bit of playing around this morning, it appears that the URL loading system will, even if you hand it an http URL, decide to use https instead. Does anyone know how to disable this behaviour -- even just for particular URLs?