Certificate Pinning and Failing Open

SSL is nice, but there are risks of fraudulent certificates being issued by rogue certificate authorities. One approach to dealing with this risk is to use certificate pinning, teaching your Android app details about the expected SSL certificate, so the app can fail if it encounters a fraudulent one. This reduces the risk of somebody with a fake cert intercepting your communications. However, it can increase other risks, as Square’s Jesse Wilson pointed out earlier today.

For example:

  • If you pin to your own certificate, that works, until you need to replace that certificate, because it is expiring or for other reasons (e.g., the Heartbleed attack “OMG replace all teh certs!” response)

  • If you pin to some other certificate up the chain towards the CA’s root certificate, that works, until the intermediary needs to replace the certificate

I imagine that this is why Android 7.0’s network security configuration’s certificate pinning implementation fails open. In other words, when you put an expiration date on a pinned certificate, when that date arrives, that pin is ignored. For planned certificate obsolescence — such as the certificate’s own expiration date — this will allow your app to keep working, even for those users who failed to update their app. Users who update their app can be moved over to a new pin for a new certificate. Since CWAC-NetSecurity is a backport of Android 7.0’s network security configuration, it too supports expiring pins.

If you elect to pin certificates, whether using network security configuration or something else:

  • Set an expiration date on the pin, and fail open. Yes, this reduces security, but only for those users running older editions of your app.

  • Have a plan for an emergency app update, in case you need to replace the server’s SSL certificate in a hurry (e.g., Heartbleed-style scenarios).

For a server that only handles mobile apps, not Web browsers, you could avoid some of this by switching to a self-signed certificate and effectively “pinning” to that. Since there is no certificate authority in the mix, you are not at risk of a certificate authority screwing up, being hacked, or being suborned into issuing a fraudulent certificate. Remember: the rationale behind a certificate authority is to help the user with a generic client app (Web browser) determine if a certificate is valid. It does not add as much value in scenarios with a specific client, such as an Android app dealing exclusively with your server.