7

I am building a simple iOS app that talks to Firebase using REST API.

Essentially, I am using NSURLSession.sharedSession().dataTaskWithRequest to connect to

https://myusername.firebaseio.com/Object.json

The app works fine in iOS 8. I am able to pass GET/PUT/PATCH/DELETE to manipulate my data. But since iOS 9 introduced ATS, I now have the https error:

NSURLSession/NSURLConnection HTTP load failed

(kCFStreamErrorDomainSSL, CFNetwork SSLHandshake failed)

I am fully aware of the workaround solution in Info.plist. However, I want to utilize the new safety feature in iOS 9.

I checked Firebase connection security (by clicking on Chrome's green lock button), and it seems to be compatible with Apple's ATS requirement.

Is my error because of the way I use NSURLSession? Or is it because of the Firebase security setup?

PS: I tested https://firebase.com and NSURLSession connects fine w/o error. My app is also simple enough that I don't require auth.

Thank you for your help.

Community
  • 1
  • 1
User5103156
  • 223
  • 1
  • 3
  • 7
  • It's hard to guess what iOS is unhappy about from that error. If you find a way to dig up more verbose error info, shoot us an email at support@firebase.com and we can see if we can pinpoint what iOS doesn't like about our SSL config. – Michael Lehenbauer Jul 10 '15 at 21:40
  • thank you. I will copy the error message and email support. – User5103156 Jul 11 '15 at 18:16

1 Answers1

16

TL;DR: It has to do with the SSL ciphers Firebase servers allow (ATS requires ECDHE only out of the box).

As mentioned, the workaround in Info.plist is to add the following:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>firebaseio.com</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
                <false/>
            </dict>
        </dict>
    </dict>

In the ATS docs, Apple only allows for the following out of the box:

TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

Setting the NSThirdPartyExceptionRequiresForwardSecrecy flag to NO in Info.plist adds the following additional ones:

TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_RSA_WITH_AES_128_GCM_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA

I disagree with their naming of the flag to be "...ExceptionRequiresForwardSecrecy" since technically DHE provides perfect forward secrecy, it's just slower than the comparable ECDHE versions. Sounds to me like there should be two flags, one being the exception to forward secrecy and one that just says that you're comfortable having a slower handshake.

Technically you could also make the excepted domain <your-firebase-app>.firebaseio.com and not have the NSIncludesSubdomains flag, but I wanted to make this sufficiently generic.

Since we allow for non ECDHE ciphers, Firebase would have to disallow them server side for this to work out of the box (unless developers wanted to start messing around with lower level stuff than NSURLRequest, see this SO post for more info on configuring SSL ciphers, but you'll spend more time doing that than adding a few lines to Info.plist).

Security-wise, we're providing comparable versions of the same ciphers, just not using the Elliptic Curves version (which provide a decent performance improvement, but exclude certain browsers [particularly mobile browsers]). More info on DHE vs ECDHE (and some other nice SSL background w.r.t Forward Secrecy is here).

For what it's worth, the realtime clients don't have this problem, so I would strongly recommend using those for a better Firebase experience :)

Community
  • 1
  • 1
Mike McDonald
  • 15,609
  • 2
  • 46
  • 49
  • 2
    Thank you for your comments. I switched to Firebase SDK. Just want to mention XCode 7 set ENABLE_BITCODE to yes by default, and would throw an error with Firebase SDK. Set it to NO would clear the message. Do you have any time frame when the new SDK would come out? – User5103156 Jul 13 '15 at 13:09
  • @User5103156 We'll look into ENABLE_BITCODE and whether we can set it on the Firebase SDK. Thanks for the heads up! – Michael Lehenbauer Jul 13 '15 at 16:28
  • As a relatively painless but arguably less secure alternative: github.com/leecrossley/cordova-plugin-transport-security – brandones Sep 29 '15 at 22:27
  • I've done the above but still get the error CFNetwork SSLHandshake failed (-9806) **only when the device is locked**. Using objective-c version of the sdk http://stackoverflow.com/questions/33922796/ios-network-connection-on-notification - any help would be appreciated :) – Mark Camilleri Dec 07 '15 at 09:21
  • I have bitCode turned OFF and I still get the error – ArdenDev Aug 04 '16 at 13:34