Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe and reliable way to enable NSAppTransportSecurity for Release configuration and disable it for Debug/Staging configurations?

The question says it all.

I am aware of NSAllowsArbitraryLoads that can be taken together NSExceptionDomains but I am bit confused by this blacklisting approach: I don't want to disable ATS for everything except specific production hosts listed by NSExceptionDomains because they are subject to change and so I would need to manage their list together with general app configuration where we have 3+ different host types for production. [Of course in a perfect world Apple would suggest us to list the hosts for which we want disable App Transport Security and have it enabled for all other hosts - Not! vice versa]

I also tried to inherit my user-defined setting $(MY_USER_SETTING) (which can support 3 different values corresponding to Debug/Staging/Release) but it does not play well with non-string types of NSAppTransportSecurity which is dictionary and NSAllowsArbitraryLoads boolean – those values just don't inherit my user-defined setting.

Background: I want to be able to see the HTTP trafic of our Debug/Staging configurations using Charles Proxy and as of iOS 9 it requires that ATS to be disabled and I want to make sure that this will not affect our Release configuration in any way!

like image 965
Stanislav Pankevich Avatar asked Oct 23 '15 15:10

Stanislav Pankevich


People also ask

How do I enable app transport security?

App Transport Security (ATS) is enabled by default when using NSURLSession , NSURLConnection , or CFURL in iOS 9 or OS X El Capitan which enforces the application to use HTTPS with TLS 1.2 for all the network communications with the back end server.

How do I allow HTTP in Xcode?

If you need to hit the HTTP request from Xcode and above you need to specify the URL in info. plist file to allow the request. You can allow all the http request by adding arbitrary load to “YES” in info. plist file.

What is the required by ATS for the HTTP connections?

ATS requires that all HTTP connections made with the URL Loading System—typically using the NSURLSession class—use HTTPS. It further imposes extended security checks that supplement the default server trust evaluation prescribed by the Transport Layer Security (TLS) protocol.

What is allow arbitrary loads iOS?

A Boolean value indicating whether App Transport Security restrictions are disabled for all network connections. iOS 9.0+ iPadOS 9.0+ macOS 10.11+


2 Answers

In contrast to what one may think (one example: WORKING WITH APPLE’S APP TRANSPORT SECURITY) NSAllowsArbitraryLoads DOES NOT work as flag which toggles between blacklisting/whitelisting modes at least it does not play well with Charles:

Blacklisting approach (DOES NOT WORK FOR ME IN IOS 9.0 - Charles does not recognize traffic from/to staging host):

Example B: ATS for all, with some exceptions

If you expect all of your domains to work with ATS, except a few that you know will not work, you can specify exceptions for where ATS should not be use, while leaving all other traffic opted in. For this scenario, you’ll want to use an NSExceptionDomains to specify the domains for which you wish to override ATS’s default settings.

Whitelisting approach (WORKS, but not really a nice way of doing this): If NSAllowsArbitraryLoads is set to YES then Application Transport Security feature is disabled for all the domains except those that listed under NSExceptionDomains.

Example C: ATS disabled, with some exceptions

Conversely, you may only want ATS to work on domains you specifically know can support it. For example, if you developer a Twitter client, there will be countless URLs you may want to load that may not be able to support ATS, though you would want things like login calls, and other requests to Twitter to use ATS. In this case you can disable ATS as your default, then specify URL which you do wish to use ATS.


Another approach described here: This One Weird Trick Makes Developing iOS Apps Against a Local Server Way Easier suggests adding "Run Script Build Phase" which uses PlistBuddy to patch application's plist file on a fly. Here's their example for making app to not use ATS when developer works against a server on his local machine (of course could be staging host as well):

/usr/libexec/PlistBuddy -c "Add :NSAppTransportSecurity:NSExceptionDomains:$LOCAL_NETWORK_NAME:NSIncludesSubdomains bool true" $INFO_PLIST
/usr/libexec/PlistBuddy -c "Add :NSAppTransportSecurity:NSExceptionDomains:$LOCAL_NETWORK_NAME:NSThirdPartyExceptionAllowsInsecureHTTPLoads bool true" $INFO_PLIST

IMO, patching Plist is a better way to conditionally disable ATS for staging hosts than using Whitelisting approach described above so we'll stick with PlistBuddy.

like image 182
Stanislav Pankevich Avatar answered Sep 28 '22 07:09

Stanislav Pankevich


I think you have your answer right there. ATS is enabled by default for all hosts. If you disable it only for staging hosts, then your production endpoints are not affected by this. That is, simply add your staging domain to the exception domains and that's that. Or did I misunderstand the specifics of your question?

like image 29
cvursache Avatar answered Sep 28 '22 08:09

cvursache