Our app is working fine on both our production and development environments but on our staging environment we get the common error:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)
From my understanding this error occurs when you try to connect to a non https
URL.
- We use ngrok for our local tunnel which has a
https
url and works fine. - For production we also use
https://ourdomain.com
and it works fine. - For staging we use
https://staging.ourdomain.com
and the error occurs.
I've seen many solutions stating to do this:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
But my employer is against the idea of disabling ATS just to get staging to work, he is also against the idea of adding an exception for our staging URL
.
Any ideas why our staging URL would be causing this error to throw or how to fix it?
ATS Diagnostic output:
Starting ATS Diagnostics
Configuring ATS Info.plist keys and displaying the result of HTTPS loads to https://staging.domain.co.
A test will "PASS" if URLSession:task:didCompleteWithError: returns a nil error.
================================================================================
Default ATS Secure Connection
---
ATS Default Connection
ATS Dictionary:
{
}
Result : PASS
---
================================================================================
Allowing Arbitrary Loads
---
Allow All Loads
ATS Dictionary:
{
NSAllowsArbitraryLoads = true;
}
Result : PASS
---
================================================================================
Configuring TLS exceptions for staging.domain.co
---
TLSv1.2
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionMinimumTLSVersion = "TLSv1.2";
};
};
}
Result : PASS
---
---
TLSv1.1
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionMinimumTLSVersion = "TLSv1.1";
};
};
}
Result : PASS
---
---
TLSv1.0
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionMinimumTLSVersion = "TLSv1.0";
};
};
}
Result : PASS
---
================================================================================
Configuring PFS exceptions for staging.domain.co
---
Disabling Perfect Forward Secrecy
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring PFS exceptions and allowing insecure HTTP for staging.domain.co
---
Disabling Perfect Forward Secrecy and Allowing Insecure HTTP
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring TLS exceptions with PFS disabled for staging.domain.co
---
TLSv1.2 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionMinimumTLSVersion = "TLSv1.2";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.1 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionMinimumTLSVersion = "TLSv1.1";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.0 with PFS disabled
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionMinimumTLSVersion = "TLSv1.0";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
Configuring TLS exceptions with PFS disabled and insecure HTTP allowed for staging.domain.co
---
TLSv1.2 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.2";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.1 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.1";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
---
TLSv1.0 with PFS disabled and insecure HTTP allowed
ATS Dictionary:
{
NSExceptionDomains = {
"staging.domain.co" = {
NSExceptionAllowsInsecureHTTPLoads = true;
NSExceptionMinimumTLSVersion = "TLSv1.0";
NSExceptionRequiresForwardSecrecy = false;
};
};
}
Result : PASS
---
================================================================================
App Transport Security is not just HTTP vs HTTPS. You need to be using properly configured servers+certificates to avoid an ATS issue. From the Apple docs [1]:
If you're on OS X 10.11 (or later), you can use nscurl to troubleshoot. Pop open a terminal and run this:
[1] https://developer.apple.com/library/ios/technotes/App-Transport-Security-Technote/index.html