Thursday, April 12, 2012

Why app developers should care about SSL pinning

In February, Arun Thampi discovered that Path was uploading users' address books to its servers.

The resulting kerfuffle served users well: Many apps–with Path leading the charge–are now much more careful about how they handle sensitive contact information and how they inform users of their intentions.

However, there's another useful reminder to draw from this episode: SSL is not a security panacea. Path's app communicated with its servers over SSL, yet third parties were able to intercept and read its traffic. How? The app wasn't pinned.

What is SSL pinning?


By default, when making an SSL connection, a client checks that the server's certificate:

  • has a verifiable chain of trust back to a trusted (root) certificate
  • matches the requested hostname

What it does not do is check that it is your certificate, the one you uploaded to your server.

When you don't know in advance to which hosts you might be connecting (e.g. in a browser), checking hostname match and chain of trust is the best you can do. In most native apps, though, you know your hosts in advance. This enables a higher level of security: You can make sure that it's your certificate that the server has presented.

This is known as SSL pinning. It offers extra protection against man in the middle (MITM) attacks, perhaps perpetrated using a compromised root certicate, or via social engineering ("Free wifi! Just add this root cert to your device!").

You don't want anyone executing such an attack on your users, ever. And there are other reasons to care:
  • You might not want people voluntarily snooping on (their own) SSL traffic to/from your app. Path probably didn't. (I'm glad, though, for privacy's sake, that things worked out how they did.)
  • Knowing the structure of an API makes it easier to find and exploit other security holes on the server.
  • Being able to easily alter server responses make it easier to find and exploit other security holes on the client. Many developers seem to assume that SSL protects you from malicious server responses. Blatant client security holes stemming from blindly trusting the server are all too common.

What apps does this affect?


The vast majority. It is incredibly easy to decrypt and observe traffic for some of the most popular apps across all categories (finance, entertainment, social networking) that many of us use daily. We've alerted every app we looked at for which we found this issue (and gave them a few months before posting this), but there are doubtless many thousands more.

At posting time, we know of four companies that implement some form of SSL pinning in their apps: card.io, Square, The Economist, and Mint.

SSL pinning is nothing new. However, with the surge in visibility of Aldo Cortesi's remarkable mitmproxy ever since the Path story broke, and with the explosion of native apps, it's high time SSL pinning was de rigueur.

How do I do implement SSL pinning?


Start by setting up mitmproxy to reproduce the problem and experience it first-hand. You should see something like the image below. We've blurred the sensitive details, but notice that the user's credentials would otherwise be plainly visible in this app:



Once you've seen how easy it is to reproduce, you can fix it! There are lots of how-to blog posts out there on SSL pinning–now that you know what to search for, half the battle is won. As for the other half...

Challenges implementing SSL pinning


There are a few problems you'll likely encounter when getting started with SSL pinning.

First, implementation is not as easy as it could be. iOS and OS X use fairly obscure C APIs, and getting this right in Android requires digging into the javax.net.ssl and org.apache.http packages. I hope that Apple and Google will make this easier soon, but in the meantime, find iOS sample code, or an Android example, read and understand it, and use it carefully. The fundamentals are not complex.

Second, what exactly do you pin to?
  • Pinning to your exact certificate will cause problems when your certificate expires and needs re-issuance.
  • Pinning to your root certificate means vendor lock-in, doesn't protect against compromised root certs, and doesn't protect against some certificate chaining attacks (cf. the iOS 4 SSL Basic Constraints vulnerability).
  • Pinning to the SPKI is just about right. Alas, in iOS, this requires manually parsing ASN.1, which is neither easy nor convenient. (Furthermore, parsing code is a common locus of buffer overflows, and such a security-critical code path is the last place you want that.) Android can use keystores generated with the Java keytool utility, although doing so requires configuration of an additional keystore provider. Again, better OS support here would be most welcome.

There's no magic answer here; understand the trade-offs and make an educated choice given your circumstances and platform.

But...


To anticipate a few obvious reactions:

Can't SSL pinning be bypassed by cracking the app?
Yes, it can. That's the nature of security. That doesn't mean you shouldn't make an attacker's job harder.

Aren't there are always more security holes?
Yes, there are. But this is a fairly easy one–both to exploit and to close.

I already have too many things to worry about.
Security is not a feature. It's part of the foundation of an app. Take the time, implement this once, and use it forever.

Why are you posting publicly about a security problem?
This is neither a new problem nor a new solution. This is a well known security weakness, yet–even after the Path story–it is not visible enough that many developers bother to fix it. Given that, sunlight is the best possible approach.


(Photo courtesy of Public Domain Photos, licensed under CC 2.0 Attribution License)


5 comments:

  1. SSL pinning is great indeed, but it' s absolutely unrelated to the Path incident.

    SSL pinning would not have prevented Path from uploading the user's address book without their consent. It would just have made it harder for the security researcher to discover this issue... Really, SSL pinning is great but for reasons that really have nothing to do with the Path incident. Hence, this article does not make a lot of sense.

    ReplyDelete
    Replies
    1. I thought it was valuable. The author does say above that SSL pinning would have made it harder for security researchers to discover the Path transgression. And that he's glad Path's privacy faux pas was discovered -- presumably because it brought the issue to light and called out the company for (depending on your level of cynicism) hoarding other people's contacts. The issue is, and this is how I read the article, that IF you are going to send sensitive data from device to server, you should use SSL pinning whenever possible. In the case of Path, parties other than Path could have intercepted private information using a man-in-the-middle attack. So even if you were OK with Path having all your private information, you would be exposing it to interception by unknown parties. That's worse than sharing with PAth because you don't know who these parties are and can not hold them accountable -- so SSL pinning guards against the greater evil of sharing with unknown and unaccountable parties.

      Delete
    2. The are a few reasons why you want to use cert pinning. The main one is to prevent your users from being exposed to rogue certificates from a CA that got compromised.

      The article barely talks about this and instead focuses on how it makes it slightly harder for security researchers to mitm their own traffic. Who cares about that ? It is true but definitely not "why app developers should care about SSL pinning".

      There are two scenarios here:
      * Another party trying to mitm the traffic for example using a rogue certificate => this is bad and this is what we want to prevent.
      * A security research trying to mitm their own traffic by modifying their own App.

      The article makes it sound like those two scenarios are similar, when they actually are completely different. Companies should not care about #2 or spend resources trying to prevent it because it can't be done anyway as the attacker has full control on the App and the phone. Cert pinning is all about preventing #1.

      Delete
  2. Hello,

    A few things are unclear to me....
    a)Why it's not ok "Pinning to your exact certificate" ?
    as i understand pinning is based on a hash of the public key right? So i guess when your current cert is close to expiration i guess you could do an update of your app to include a 2nd hash of the new certificate....(but ofc. probably some users will not do the update)

    b) you say "Pinning to the SPKI" would be just about right. i'm not sure here, who's public key are we talking about? the root CA? or i guess an intermediary CA in the chain?

    Thanks.

    ReplyDelete

Note: Only a member of this blog may post a comment.