iOS 9 has a new security feature that improve how an app can access the web or… how the web can access an app and the device itself.
What is it
From the official documentation about the App Transport Security (ATS):
It improves the privacy and data integrity of connections between an app and web services by enforcing additional security requirements for HTTP-based networking requests. […] Attempts to connect using insecure HTTP fail. Furthermore, HTTPS requests must use best practices for secure communications.
This means that an iOS device will automatically block connections to a server when its SSL, TLS certificates and configuration are either outdated or insecure.
Obviously some backend / API / web views related bugs you could get from now on, might be due to those changes.
What To Do
To make sure your app can still access its outdated and insecure backend and APIs, you need to add exceptions into your Plists files.
In few words, just tell your device to ignore the fact that those backends are dangerous.
Once you know which backends are insecure, you have to specify their domain names under the
NSAppTransportSecurity of the Plist files.
For example, if your api on the machine behind
my.api.domain.com is insecure, add and adapt the following at the end of every info.plist of your project (for each target):
If the API is on an updated server, you do not need to add any exception on your PList files.
List of keys and description of server-specific exceptions to your app’s overall intended network behavior:
|NSIncludesSubdomains||Boolean||Apply the ATS exceptions to all subdomains.|
|NSExceptionAllowsInsecureHTTPLoads||Boolean||Allows insecure HTTP loads.|
|NSExceptionRequiresForwardSecrecy||Boolean||Override the requirement that a server support forward secrecy or not.|
|NSExceptionMinimumTLSVersion||String||Minimum TLS version supported.|
It is also possible configure exceptions of a domain whose security attributes you do not control (i.e.: third party libraries).
Once again, only set what you need, make sure you do not disable any security feature without reason.
What NOT to do
You could also disable the complete ATS feature and let the app access every single insecure URLs.
Of course this easy dirty solution is not the right one, but in case of despair it might help quite a lot.
How to know what exceptions do you need?
If you do not know which exceptions you really need, there is an easy way to test the backend your app will access.
Open the terminal and use the following command:
$> nscurl --ats-diagnostics https://base.url.of.my.api.com
And for more information:
$> nscurl --ats-diagnostics --verbose https://base.url.of.my.api.com
All kind of tests will be done: with or without SSL, different TLS versions, etc.
The result displayed should be able to help you setting for each domain the exceptions you need.
On StackOverFlow this thread is the most valuable one, its second answer is great explanation while the third one tells you what to do (while being security-safe).