HTTPClient: App Transport Security policy issues on OS X


#1

Apple tries to enforce HTTPS for all connections. They have a new thingie called "App Transport Security". This occurs on OS X El Capitan and I'm pretty sure, that it also happens on iOS 9.

reproduction: Open Demo, goto "HTTP", click "Download URL Contents"

result:
Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSUnderlyingError=0x6180004514c0 {Error Domain=kCFErrorDomainCFNetwork Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." UserInfo={NSErrorFailingURLStringKey=http://www.google.com/, NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection., NSErrorFailingURLKey=http://www.google.com/}}, NSErrorFailingURLStringKey=http://www.google.com/, NSErrorFailingURLKey=http://www.google.com/, NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.}

It's possible to adjust this feature via the Info.plist. But it would be pretty slick, if the entries in question could be configured via the Introjucer.

related links:
http://stackoverflow.com/questions/32631184/the-resource-could-not-be-loaded-because-the-app-transport-security-policy-requi

here's described, how you can disable ATS for specific domains:
https://community.embarcadero.com/blogs/entry/how-to-use-custom-info-plist-xml-to-support-ios-9-s-new-app-transport-security-feature

As mentioned: it would be really cool to have a list in the XCode target in the Introjucer to set specific domains to disable https for. After all HTTPS is a good thing, would be a shame, if it would just be disabled by default.

Best,
-- Benjamin


WebBrowserComponent, JavaScript and asm.js
#2

Hi,

OK, I'm not sure we should add those ATS exception options to the Introjucer/Projucer explicitly, because it would essentially be encouraging people to bypass ATS?

We ran into the exact same problem with some of our apps here at ROLI, and we fixed it by adding those extra plist tags (your second link) to the "Custom Plist" field in the Introjucer config. That's an effort of 1 minute (copypaste, put your URL in, re-save project) and does the job just fine...


#3

then probably you want to change the default URLs in the Demo to https:// and update the documentation? And also get an TLS certificate for juce.com so that user credentials are no longer transmitted unencrypted?

Thanks for the pointing me to the custom plist field - I did not notice that before.

Best,
-- Benjamin


#4

Ran into this today and wondered if it would make sense to add those settings to the Info.plist of Introjucer at least?

If I hadn't just had the same issue with another app yesterday, I would still wonder why juce.com is not ready to check for updates. This should be enabled with the Introjucer Xcode project by default.


#5

Pretty sure I ran into this issue recently too. I ended up modifying the info.plist manually.


#6

Sorry for resurrecting this, but I am unable to bypass this security check.

Even tried to bypass it for every domain and it still fails. This is my final attempt:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist>
  <dict>
    <key>CFBundleExecutable</key>
    <string>${EXECUTABLE_NAME}</string>
    <key>CFBundleIconFile</key>
    <string/>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleName</key>
    <string>project-name</string>
    <key>CFBundleDisplayName</key>
    <string>project-name</string>
    <key>CFBundlePackageType</key>
    <string>BNDL</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0.0</string>
    <key>CFBundleVersion</key>
    <string>1.0.0</string>
    <key>NSHumanReadableCopyright</key>
    <string>Universless</string>
    <key>NSHighResolutionCapable</key>
    <true/>
    <key>NSAppTransportSecurity</key>
    <dict> 
      <key>NSAllowsArbitraryLoads</key><true/>
    </dict>
  </dict>
</plist>

I am only building a vst right not, so I have just this one Info-VST.plist in the project navigator. Is it possible this to be shadowed by another plist?

Update:

  • BTW, this is where I get the exception - I am trying to post data to a local server:

    bool doPostLikeRequest = true;
    int statusCode = 0;
    InputStream* stream = URL (“http://localhost:5000/waveform-block”)
    .withPOSTData (jsonText.toStdString ())
    .createInputStream (
    doPostLikeRequest,
    nullptr,
    nullptr,
    “application/json”,
    1000,
    nullptr,
    &statusCode,
    0,
    “POST”
    );

    if (statusCode != 200)
    {
    DBG (“Error posting a stream block.”);
    }

    if (stream != nullptr)
    {
    delete stream;
    }

I just discovered URL in the library and want to replace restclient-cpp in my code, so perhaps I am not using URL correctly for this POST request?


#7

I’ve rebuilt Plugin Host with this addition to its .plist:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <false/>
  <key>NSExceptionDomains</key>
  <dict>
    <key>localhost</key>
    <dict>
      <key>NSExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <key>NSIncludesSubdomains</key>
      <true/>
    </dict>
  </dict>
</dict>

Aaand I’m using the same for the plugin and request are getting through.


#8

More info on the keys here:
https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33

I also saw messages from people saying that after the end of 2016 Apple will reject apps not conforming to ATS.
But there will be a key specifically for web content through browsers: NSAllowsArbitraryLoadsInWebContent.

How do you deal with cases where the user chooses the IP address or URL to connect to, and the communication is not critical and happens over http (not https)?
You don’t know the URLs or IP addresses in advance, so you can’t add them in your plist…
Or can a program add exceptions dynamically at run-time? That would surprise me, as that would defeat the purpose of declaring the exceptions in the application properties in the first place…

Edit:
Looks like the docs say that NSAllowsArbitraryLoads is meant for such cases:
“Enable this key for cases where your app allows the user to specify connection to an arbitrary URL.” But it remains to be seen what happens after end 2016 with this key then.