iOS 9 and Ionic Side Menus

I encountered an issue with Ionic side menus where a previous view would partially obscure the current view. I updated everything, checked all my JS and HTML templates, verified links and state transitions, all to no avail.

I was stuck for quite a while until I finally decided that it’s probably an iOS-specific issue. A search then led me to this Ionic blog entry from 2 months(!) ago: http://blog.ionic.io/ios-9-potential-breaking-change/. I downloaded and applied the patch and that was it.

The issue is caused by an iOS 9 bug that affects AngularJS and thus Ionic. It’s supposedly “isolated to intermittent UI/navigation issues on some apps”. And, of course, I was one of the lucky ones. I can’t believe it hasn’t been fixed yet!

iOS 9 and the Firebase REST API

I was playing around with the Firebase REST APIs when I encountered the following SSL error:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL...

After some research, I found out that iOS 9 enforces App Transport Security or ATS which, according to Apple, “enforces best practices in the secure connections between an app and its back end”.

But I am using secure connections! After further research I found out that problem with the Firebase servers, specifically the SSL ciphers they allow.

By default, apps use only a specific set of ciphers for SSL communications:

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 NSAppTransportSecurity option will include the following ciphers, which the Firebase servers do allow:

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

Setting the NSAppTransportSecurity option entails adding the following into the app’s Info.plist:

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

DHE stands for Diffie-Hellman Exchange. ECDHE stands for Elliptic-Curve Diffie Hellman Exchange. They both offer forward secrecy but ECDHE is just faster. So the NSThirdPartyExceptionRequiresForwardSecrecy is a bit of a misnomer.

Now I wonder why Firebase doesn’t just add support for ECDHE?

More at StackOverflow.