How do I load an HTTP URL with App Transport Security enabled in iOS 9? [duplicate]
Asked Answered
H

8

468

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?

Haas answered 9/6, 2015 at 12:15 Comment(5)
See this: #31255225Homosexuality
I just wrote a guide to verify your Webservice for App transport security, that might helpful medium.com/@Mrugraj/app-transport-security-b7910c4fc70fGrasshopper
not working for iOS 9.3Alsacelorraine
I have noticed something, this question was asked Jun9 but the link that makes this the duplicate was Jul6...Renewal
How to specify IPAddress instead of the domain in NSExceptionDomains?Kotto
A
732

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)

Archil answered 9/6, 2015 at 12:15 Comment(15)
NSExceptionDomains should be the preferred approach to selectively remove individual domainsChorus
Note that CFNetwork.framework uses different strings than presented in the session for most of these keys, in beta 1: NSTemporaryExceptionAllowsInsecureHTTPLoads, NSTemporaryExceptionMinimumTLSVersion, NSTemporaryExceptionRequiresForwardSecrecy, NSTemporaryThirdPartyExceptionAllowsInsecureHTTPLoads, NSTemporaryThirdPartyExceptionMinimumTLSVersion, NSTemporaryThirdPartyExceptionRequiresForwardSecrecyArchil
There's now a Technote out at developer.apple.com/library/prerelease/ios/technotes/…Wishful
What works is NSIncludesSubdomains and NSTemporaryExceptionAllowsInsecureHTTPLoads to <true />.Carnation
The info in this answer didn't work for me.Yacketyyak
Thanks @NikYo for pointing out the typo in NSExceptionAllowInsecureHTTPLoads.Archil
More details in #711 technote : developer.apple.com/videos/wwdc/2015/?id=711Carlow
Is this working for anyone on xCode 7 beta 6? I am having no luck. Even tried the NSTemporary values.Kif
As a side note: IP addresses don't work. In my case I wanted to exclude my development server machine (on local network) by IP... this did not work. I added an alias to the hosts file and used the alias. For example devpc instead of 192.168.1.99. Then add devpc into the NSExceptionDomainsChastitychasuble
Heads up: using NSAllowsArbitraryLoads could get your app rejected. See this conversation: github.com/AFNetworking/AFNetworking/issues/2779Vertu
I tried your suggestion to no avail please have a look at my question #32962655 thanks.Plasma
@pechar how to do that ? I have 3 IP addresses for my different environemtn (all testing), and all using self-signed HTTPS. I tried every answer in here, but unable to proceed.Accumbent
@Accumbent very simple just open your Terminal and type the following sudo nano /private/etc/hosts you will be asked for the admin password. Then add the necessary aliases and exit using Ctrl+X then pressing 'Y' to confirm save. Then flush the DNS cache using dscacheutil -flushcache; sudo killall -HUP mDNSResponderChastitychasuble
This will not work in iOS 10 after december 2016 any more. Your apps must not have these keys in your info.plist, otherwise your apps are going to reject from app store.Rudolph
@AbuzarAmin comment about being rejected is not correct.Primateship
G
114

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.

Gyroscope answered 10/6, 2015 at 8:54 Comment(10)
The best answer that provides an example of simple settings.Revetment
It doesn't work if using IP Address. can anyone help me to exclude IP address instead of domain name ?Accumbent
just wanted to say, that the domain should be enter WITHOUT "http://" at the beginningEvelyne
this creates a high risk for App rejection As Apple is very clear in that they intend to reject apps who use this flag without a specific reason. The main reason to use NSAllowsArbitraryLoads& 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.Oruntha
This will not work in iOS 10 after december 2016 any more. Your apps must not have these keys in your info.plist, otherwise your apps are going to reject from app store.Rudolph
@Accumbent for IP address try adding .xip.io to the end of the address and put xip.io in your NSExceptionDomains (xip.io)Choirmaster
@AbuzarAmin Is there any alternative for adding Exception Domains in App Transport Security Settings in iOS 10 and later?Comity
@Comity you can still add exception Domains in App Transport Security Settings but you must have some strong reason for this otherwise App Store will Reject your App.If you have enterprise Application then you don't have to worry about this at all.Rudolph
@AbuzarAmin Exception Domains no more works for iOS 10 and later. Using only NSAllowsArbitraryLoads to Yes works for iOS 10 and later.Comity
Provided link doesn't workBritt
W
61

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.

Winthorpe answered 28/9, 2015 at 7:37 Comment(2)
This helped me a lot during testing of an app where a SSL cert was not available.Symons
This will not work in iOS 10 after december 2016 any more. Your apps must not have these keys in your info.plist, otherwise your apps are going to reject from app store.Rudolph
P
38

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>
Perrin answered 24/9, 2015 at 14:40 Comment(3)
I would strongly advise against option 1 because it could hide issues that will bite you in your production app (for example, if you are using 3rd party non-secure domains).Gangland
I appreciate the feedback but, personally, I don't really think that deserves a down vote. I'm not saying it's the recommended solution. I'm just offering a different option. Obviously, I would recommend excluding specific domains (if HTTPS isn't available) but kcharwood has already given that answer. In any case, I'll leave it up to you. Just thought I'd give my reasoning.Perrin
Understood. This seems like the kind of issue beginners may search about, see the suggestion to allow arbitrary loads, and follow without thinking about any consequences. With the solution to allow arbitrary loads for any app release, it's up to Apple to reject the app. Having different settings for different build configurations could lead to someone having the app working during development, but the archived build could be broken. I'm unable to remove my downvote, but if you edit the answer with some potential pitfalls of option 1 I'd be happy to un-downvote it.Gangland
U
31

I have solved as plist file.

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

enter image description here

Unbalanced answered 8/10, 2015 at 5:54 Comment(7)
This will not work in iOS 10 after december 2016 any more. Your apps must not have these keys in your info.plist, otherwise your apps are going to reject from app store.Rudolph
then what should we do from ios 10 ??Huddersfield
You shall not use HTTP anymore. If you don't have a choice, use the method in the answer, with NSExceptionDomainsSizemore
@AbuzarAmin where you did read about this? I'm using the same approach in one of my app and that app is working fine. what's the alternative way to achieve this on iOS 10 and above?Asylum
@Suryakant it was announced in WWDC videos. If your app is on App Store then it will create problem when you submit your app to App Store for review.Rudolph
@AbuzarAmin but untill your app have strong reason to use that key, I read somewhereAsylum
yup if you can justify to Apple that why are you using it , then there will be no problem.Rudolph
P
23

Configurations above didn't work for me. I tried a lot of combinations of keys, this one work fine:

enter image description here

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>mydomain.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>
Pomace answered 25/9, 2015 at 9:51 Comment(5)
This also worked for me on Appcelerator 4.0.0.GA and xcode7Ergotism
I'm trying to allow my app to send http requests to my local rails server at localhost:3000...what would I put in for the domain then? I've tried "localhost", "localhost:3000", localhost:3000, etc...any ideas? Thanks for the help in advance!Stair
@Stair localhost:3000Pomace
@Stair - just plain old localhost worked for me. Also, you need to be sure that your request url is http://localhost:3000. NSURLSession data tasks to localhost:3000 without the preceding "http://" won't work.Pizarro
This will not work in iOS 10 after december 2016 any more. Your apps must not have these keys in your info.plist, otherwise your apps are going to reject from app store.Rudolph
S
18

Compiling answers given by @adurdin and @User

Add followings to your info.plist & change localhost.com with your corresponding domain name, you can add multiple domains as well:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>localhost.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <false/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <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>
</plist>

You info.plist must looks like this:

enter image description here

Stocks answered 10/8, 2015 at 13:44 Comment(5)
"localhost" or "localhost.com"?Hector
localhost must work, fortunately localhost.com is working as well didn't noticed thanks, but please try localhostStocks
This will not work in iOS 10 after december 2016 any more. Your apps must not have these keys in your info.plist, otherwise your apps are going to reject from app store.Rudolph
really, please share link?Stocks
It looks like the values are wrong, in most other answers, at least the AllowsInsecureHTTP is set to true.Aleman
R
16

Here's what worked for me:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key><!-- your_remote_server.com / localhost --></key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
        </dict>
    <!-- add more domain here -->
    </dict>
</dict>

I just wanna add this to help others and save some time:

if you are using: CFStreamCreatePairWithSocketToHost. make sure your host is the same with what you have in your .plist or if you have separate domain for socket just add it there.

CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)/*from .plist*/, (unsigned int)port, &readStream, &writeStream);

Hope this is helpful. Cheers. :)

Renewal answered 19/10, 2015 at 9:8 Comment(1)
This is preferred way of allowing Exception Domains instead of making open to all (i.e. by using Arbitary Loads to Yes).Emlynne

© 2022 - 2024 — McMap. All rights reserved.