Wednesday, April 27, 2011

Fiddling with Chromium's new certificate pinning

Over the past few years, there have been various high-profile incidents and concerns with the Certificate Authority-based infrastructure that underpins https connections. Various different efforts are underway to tackle the problem; many are enumerated here:

http://googleonlinesecurity.blogspot.com/2011/04/improving-ssl-certificate-security.html

And in terms of things baked directly into the browser, we have things like Firefox's Certificate Patrol add-on:

https://addons.mozilla.org/en-US/firefox/addon/certificate-patrol/

My colleague Adam Langley summarized some features and directions we've been exploring in Chromium recently, it's a good read:

http://www.imperialviolet.org/2011/05/04/pinning.html

These features can also be controlled via the command-line, so to give a glimpse of the future, I present to you:

Twitter Like A Boss

Run Chrome (v12 dev channel or newer required) with a command line like this:

google-chrome --user-data-dir=/tmp/chrome_twitter --incognito --disable-plugins --proxy-server=localhost:1 --proxy-bypass-list=https://twitter.com,https://*.twitter.com,https://*.twimg.com --hsts-hosts='{"df0sSkr4gOg4VK8d/NNTAWFtAN/MjCgPCJ5ml+ucdZE=":{"expiry":2000000000.0,"include_subdomains":true,"mode":"strict","public_key_hashes":["sha1/TXoScD1SXPfhmRO8ACTPrkXD9Yk="]},"tGm+XsbBPK211uMWtg2k071vijQkuVLvd62QzfNFol8=":{"expiry":2000000000.0,"include_subdomains":true,"mode":"strict","public_key_hashes":["sha1/06curQTaPH4PGumbNSeL79da23s="]},"wZU3atDOXaxKkaRgSdlWwB4UYjulRq46SGnIBij5I98=":{"expiry":2000000000.0,"include_subdomains":true,"mode":"strict","public_key_hashes":["sha1/O6hykhOmHJ5HQUREC0DTDeu6+mE="]}}' --user-agent='LIKE A BOSS'

(You'll need to edit a couple of things such as the command name and the temp directory if you're on Windows or Mac).

If you wish to connect securely to Twitter, well it pretty much does so... like a boss. It does the following things and defends against the following situations:

  • The --user-data-dir flag loads Twitter in a new profile so that you get a new Chrome instance and therefore new cookie jar. Therefore, carelessly clicked links in your other browsing windows won't get you XSSed.

  • The --incognito flag applies the usual incognito changes; notably, things like profile photos won't be cached to disk; might be useful if you're an activist.

  • --disable-plugins is strictly unnecessary since Twitter generally isn't using plug-ins. However, any "secure" command line should likely include that flag.

  • The --proxy-server=localhost:1 is a good defensive catch-all which will stop any site traffic being sent by your browser unless it is whitelisted. Specifically, a http://bit.ly/ link to an XSS payload won't work on you. (You'll need to paste such links into an alternate browser which shouldn't be logged in to Twitter). This will also stop non-pinned https requests going out (which might otherwise compromise the integrity of the main page). Mixed-content bugs, cookie forcing and failure to mark cookies "Secure" will also be mitigated.

  • --hsts-hosts is the magic. It locks twitter.com, api.twitter.com and twimg.com such that SSL traffic from/to Twitter will only be accepted if the leaf SSL certificate's public key is exactly what we expect. It's called "certificate pinning", and along with HSTS, it defends against any compromised root CA, Comodo-gate, Tunisia-like sslstrip attacks, and the "evil country owns firewall + CA" situation.

  • --user-agent='LIKE A BOSS' is strictly optional, depending on your mood.

The above command line isn't finished. Although Twitter seems to run fine, there are under-the-hood failures to scribe.twitter.com and other places because I haven't added the correct certificate pin for that host. The above will break if any of the leaf certificate public keys change (this doesn't necessarily happen on expiry rollover but may otherwise happen for various reasons).

Hopefully this demo is compelling. The plan is to push this technology more and more under the covers so that it happens for less technical users who have an empty command line!