App Transport Security and local networking

Hi,


it seems that "App Transport Security" is also enabled by default for communication on the local network (http transfers between devices on the same wifi network).

In many cases such wifi devices (e.g. wifi based sd cards, mobile wifi harddisks) do not support https; so http needs to be used.

What is the recommended way to handle these cases as the domain based exception cant be applied here?
Is there any way to disable App Transport Security for private networks?


Cheers,


Hendrik

+1


Suggestion: Introduce a key NSAllowsArbitraryLoadsLocalNetworkOnly. When this key is set to true, it allows unencrypted http communication between devices on the same local network (IPv4 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 and IPv6 fd00::/8, and 127.0.0.1 for development purposes).


This is a HUGE issue for our company. We need to upload firmware on our devices through http requests over the local network, and requiring these devices to have https servers running is onerous (if not impossible). We would like to implement ATS on our apps for non-local traffic, but are unable to.

To update on this issue, Apple engineering closed my enhancement request as Behaves Correctly. After pressing them on the issue, (I'm not sure I'm allowed to publish bug report responses here in a public forum so I'll paraphrase) the response that they gave in support of denying localhost by default was an example of a linked advertising framework which secretly communicates with localhost and sends data to a remote server. If localhost is denied by default, then the developer can see this is happening.


Frankly, it seems overzealous; developers should already be running good firewall software which would alert them to the same thing. But it appears that ship has sailed and we're stuck with putting localhost exemptions in every project.


The OP's issue seems more pressing and the only workaround of "**** ATS from orbit" is not a workaround at all. Communicating with local devices, or testing apps on devices with local servers, is kind of fubar'd at the moment when IP addresses aren't accepted as valid exemptions.

One workaround is to edit the /etc/hosts file on your Mac and add a line like this at the end of the file (you need to do this as superuser/root):

127.0.0.1 apple.ninja


This makes "localhost" accessible via a fully qualified hostname (apple.ninja) and you can use the standard ATS feature to allow HTTP traffic to that "domain":


<key>NSAppTransportSecurity</key>
        <dict>
                <key>NSExceptionDomains</key>
                <dict>
                        <key>apple.ninja</key>
                        <dict>
                                <key>NSIncludesSubdomains</key>
                                <true/>
                                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                                <true/>
                        </dict>
                </dict>
        </dict>

While researching this as part of an official DTS incident I came across a reasonably nice workaround that I thought I’d share: namely, if the target device supports Bonjour you can add an ATS exception for “local” and everything within “local” will just work.

As part of its operation Bonjour service discovery requires that every device has a .local name. Specifically, when you resolve a service you get back:

  • the device’s .local name (A) — In NSNetService, this is the

    hostName
    property
  • the IP addresses associated with that name (B) — In NSNetService, this is the

    addresses
    property.
  • the port number on which to connect (C) — In NSNetService, this is the

    port
    property.

For example, if I browse for HTTP services on my local network:

$ dns-sd -B _http._tcp. local.
Browsing for _http._tcp..local.
DATE: ---Thu 15 Oct 2015---
11:01:51.968  ...STARTING...
Timestamp     A/R    Flags  if Domain   Service Type    Instance Name
11:01:51.969  Add        3   4 local.   _http._tcp.     Darth Inker
^C

I get back a list of services including

Darth Inker
. If I resolve that:
$ dns-sd -L "Darth Inker" _http._tcp. local.
Lookup Darth Inker._http._tcp..local.
DATE: ---Thu 15 Oct 2015---
11:02:42.973  ...STARTING...
11:02:43.289  Darth\032Inker._http._tcp.local. …at… darth-inker.local.:80 …
^C

I get the .local name (

darth-inker.local.
, point A) and the port number (80, point C). Finally, I can resolve the .local name into IPv4 and IPv6 addresses (point B).
$ dns-sd -q darth-inker.local. A
DATE: ---Thu 15 Oct 2015---
11:03:38.570  ...STARTING...
Timestamp     A/R Flags if Name                 Type  Class   Rdata
11:03:38.571  Add     2  4 darth-inker.local.   Addr   IN     192.168.1.40
^C
$ dns-sd -q darth-inker.local. AAAA
DATE: ---Thu 15 Oct 2015---
11:03:41.963  ...STARTING...
Timestamp     A/R Flags if Name                 Type  Class   Rdata
11:03:41.963  Add     2  4 darth-inker.local.   AAAA   IN     FE80:0000:00…
^C

The point here is that I don’t need to use these IP addresses in order to connect to the service. I can simply put the .local name into a URL and pass that URL to NSURL{Session,Connection}.

This is relevant for ATS because, if you always connect via the .local name, you can add an ATS exception for everything in the “local” domain (see below) and ATS will get out of the way.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>local</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSIncludesSubdomains</key>
            <true/>
        </dict>
    </dict>
</dict>

Obviously this only works if the target device supports Bonjour but, hey, in my opinion, devices without Bonjour support are broken anyway (-;

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Another relatively simple workaround is xip.io, which may be more useful for many applications. A DNS call to (for example) 10.0.1.8.xip.io will resolve to 10.0.1.8, allowing use of the domain instead of the IP address for the NSExceptionDomains key.


By the way, NSAllowsArbitraryLoads did not work for me either. However, the xip.io workaround is sufficient for me (and superior to localhost).

Another relatively simple workaround is xip.io …

Cool. I hadn’t seen that before. Thanks for sharing.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

devices without Bonjour support are broken anyway (-;


Same here...


I have an APP that does HTTP connexion ( openweathermap) , HTTPS connexion on the internet (personnal data for the users) and that does HTTP connexion to a local network device ( IOT device discovered via Bonjour and after that we use IP connexion in HTTP to have faster response time). Since IOS 9 it's not possible to have this device working with IOS via IP.


Everybody should remember that private IP (192.168.*.*, 10.*.*.*) can't have HTTPS connexion with valid certificates. And that many devices are not "bonjour" compatible. We need something like NSAllowsArbitraryLoadsLocalNetworkOnly

I need this feature too. Are there any news ?

I also need this feature. Any news ?

This does not seem to be working for tvOS.


2016-05-18 08:00:15.672 Hero[8664:3335716] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

2016-05-18 08:00:15.673 Hero[8664:3335690] [Error]: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection. (Code: 100, Version: 1.13.0)

My info.plist looks like this:

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



I'm making a call to http://localhost:1337/parse and I get the App Transport Error. I'm using the Parse SDK to make the call. I don't know if that makes a difference. I haven't dug into it on the Parse side yet.

While editing the info.plist didn't work for me. I followed these instructions and now everything works as expected.


http://stackoverflow.com/questions/31254725/transport-security-has-blocked-a-cleartext-http

Hi,


I started this thread almost a year ago, because of the issues of App Transport Security in combination with local/private networks. The workaround eskimo posted for bonjour based hostnames (.local) is nice, but not a solution for every case. In my opinion something like NSAllowsArbitraryLoadsLocalNetworkOnly is still needed.


I just looked throught the iOS 10 Beta API docs and unfortunately I can't see any addtions that go into that direction. The only new addition seems to be NSAllowsArbitraryLoadsInWebContent, which is only relevant for Web-Content (WKWebKit).

Apple today at WWDC also announced, that ATS is mandatory by the end of 2016 for all AppStore submissions.

I am aware that iOS 10 is in Beta and there might be still additions, but the current state of things makes me quite worried.


The general concept of ATS and protecting users is great, but for applications doing data transfer on the private/local network its use is just not practical in many cases (there are plenty of examples in this thread).


@eskimo: You know the internal processes at Apple better than any of us here. There were numerous bug reports filled for this issue in 2015 and also (I assume) several DTS incidents. What can we do that the issue gets the required attention and the actual framework developers take a look at it?


Cheers,


Hendrik

I second this request.

We manage the app of a connected appliances company, but unfortunately we don't get to design the hardware specs and protocols, so neither bonjour nor HTTPS for us 😟

xip.io might work, but we cannot rely on the 37signals magnanimity forever, I believe.

Without something like NSAllowsArbitraryLoadsLocalNetworkOnly our iOs app will be completely useless in 2017; I believe we're not alone in this, as this thread clearly shows.

We are in the same situation having an app which is in fact a proxy between web media and local network. A lot of web servers does not impement HTTPS and communications over local network too. It seems our app will be absolutely useless without NSAllowsArbitraryLoads. There must a procedure/approval for apps like our similar to setting for example Background modes for apps. I am sure a lot of apps are in our situation.

Support NSAllowsArbitraryLoadsLocalNetworkOnly

I too came back and looked for this support after the iOS 10 annoucement.

I just looked throught the iOS 10 Beta API docs and unfortunately I can't see any addtions that go into that direction.

Indeed. Sad Quinn is sad )-:

What can we do that the issue gets the required attention and the actual framework developers take a look at it?

This is a sufficiently well-known issue that I used it as an example of “reasonable justification” in my recent ATS update. I, and the ATS team, certainly got a lot of feedback about this issue during the labs at WWDC (-: It’s possible that the situation with ATS and local networking might change prior to the new ATS requirement being enforced but, if it does not, you will have to ship with

NSAllowsArbitraryLoads
.

Keep in mind that, even if we did add something like

NSAllowsArbitraryLoadsLocalNetworkOnly
today, you’d still need
NSAllowsArbitraryLoads
as long as you support iOS 9.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for the response, Quinn.

It's good to hear, that there is still hope. Something like NSAllowsArbitraryLoadsLocalNetworkOnly would still help and make dealing with App-Review easier.

Thanks so much for keeping us updated.


Cheers,


Hendrik

Hi,


Really appreciate all the responses and information you've provided. I'd just like to follow up and find out if there's been any new information since the last update.


We have an application that communicates to several devices on the local network. Updating these devices to support HTTPS (and in some case, this may not be possible at all) will be a significant endeavor for us. Has there been a path forward or solution for people and companies who are in this particular situation?


Thanks!

-ah

it seems we will get the "NSAllowsLocalNetworking" key

Indeed. Yay!

Just for the record, while there were lots of bugs filed about this (thanks everyone!), the specific change was made as (r. 27111836).

I tried this out for myself (both in the simulator and on iOS 10.0b4 hardware) and it seems to work well. The only gotcha I found is that it doesn’t allow absolute domain names (r. 27655708). For example,

NSAllowsLocalNetworking
enables access to
http://guy-smiley.local
but not to
http://guy-smiley.local.
(note the trailing dot). This might trip you up if, for example, you build the URL from NSNetService’s
hostName
property, which always returns an absolute domain name.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Very goood news. I tried iOS 10 beta both on the simulator and on an iPad and observed the same behavior with ".local." host names.


It seems that if you actually only use IP addresses, no exception is needed any more. My app was able to perform clear HTTP requests to 127.0.0.1 or 192.168.100.2 (a local network wifi address) without any ATS section in the app .plist file. So it seems that I could simply remove any ATS exception from the app and submit it as is in 2017.


This raised a question though: If I submit my app without ATS exception, which should work on an iOS 10 device, how will it behave if the app is installed on iOS 9?

If I submit my app without ATS exception, which should work on an iOS 10 device, how will it behave if the app is installed on iOS 9?

Clearly iOS 9 does not support

NSAllowsLocalNetworking
. If you want to support iOS 9 and 10, you’ll need to also set
NSAllowsArbitraryLoads
. Make sure you explain this to App Review as part of your “reasonable justification”.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Doesn't this defeat the purpose of the new iOS 10 exceptions: In order to maintain iOS 9 compatibility (A likely scenario for most apps submitted next year) the developer will have to request a broader exception even if not needed. If granted it effectively allows an app to use clear http anywhere.

Doesn't this defeat the purpose of the new iOS 10 exceptions …

What alternative do you propose?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

The new exception being tied to iOS 10 only I don't see any solution on the developer side. Would it be theorically possible for an app built with Xcode 8 compatible with iOS 10 and 9 to be processed by Apple before distribution so that the new exceptions (LocalNetworking) translate into the broader NSAllowsArbitraryLoads when installed on iOS 9? This way, at least the app developer does not have to request NSAllowsArbitraryLoads and justify it.

Once again, highly hypothetical.

App Transport Security and local networking
 
 
Q