June 23, 2014

In Defense of JavaScript Crypto

Filed under: Security — Nate Lawson @ 4:05 am

Thai Duong wrote a great post outlining why he likes JavaScript crypto, although it’s not as strong a defense as you might guess from the title. While he makes some fair points of some limited applications of JavaScript, his post is actually a great argument against those pushing web page JS crypto.

First, he starts off with a clever Unicode attack on JS AES by Bleichenbacher. It is a great way to illustrate how the language, with its bitwise and type hostility, actively works against crypto implementers. Though Thai points out lots of different ways to work around these problems, I disagree that it’s clear sailing for developers once your crypto library deals with these issues. You’ll get to pick up where your low-level library left off.

Oh, and those of you were looking for defense of web page crypto for your latest app? Sorry, that’s still dumb. Google’s End-to-End will only be shipped as a browser extension.

The most ironic part of Thai’s post involves avoiding PCI audit by shipping JS to the browser to encrypt credit card numbers. Back in 2009, I gave a Google Tech Talk on a variety of crypto topics. Afterwards, a Google engineer came up to me and gave exactly Thai’s example as the perfect use case for JavaScript crypto. “We avoid the web server being in scope for PCI audits by shipping JS to the user,” he said. “This way we can strip off the SSL as soon as possible at the edge and avoid the cost of full encryption to the backend.”

He went on to describe a race-condition prone method of auditing Google’s own web servers, hashing the JS file served by each to look for compromised copies. When I pointed out this was trivial to bypass, he said it didn’t really matter because PCI is a charade anyway.

While he’s right that PCI is more about full employment for auditors & vendors than security, news about NSA tapping the Google backbone also shows why clever ways to avoid end-to-end encryption often create unintended weaknesses. I hope Google no longer underestimates their exposure to nation-state adversaries after the Snowden revelations, but this use-case for JS crypto apparently hasn’t died yet.


  1. Have you looked at Mylar ? http://css.csail.mit.edu/mylar/ https://www.usenix.org/conference/nsdi14/technical-sessions/presentation/popa

    What is interresting about Mylar is they created a generic browser extension that does signed code verification that can work with multiple webapplications.

    I don’t think they did it right, but if they got it completely right, somebody could go to W3C to make it a standard so it can be included in all browsers.

    Comment by Lennie — June 23, 2014 @ 5:42 am

    • It’s a good start but we’ll need a lot more than that. Compartmentalization beyond same-origin, for example.

      Comment by Nate Lawson — June 23, 2014 @ 9:27 pm

      • Yes, the same origin policy is the, euh… first layer of defense.

        From the top of my head modern browsers come with 3 newer systems which can be used by webdevelopers for compartmentalization and reducing privileges:
        – Content Security Policy
        – Webworkers
        – the iframe sandbox attribute

        When there is a need to communicate with an iframe or webworker or even other page/window postMessage will be used.

        Comment by Lennie — June 23, 2014 @ 10:39 pm

      • And outside of the browser there is also the CORS-header which allows the developer of the server part to allow some exceptions to the same origin policy.

        Comment by Lennie — June 23, 2014 @ 10:45 pm

      • Forgot about an other modern feature: ECMAScript 5 (also called Javascript by most people) has ‘strict mode’.

        Comment by Lennie — June 23, 2014 @ 10:52 pm

  2. What do you think of the use of javascript crypto for client-side encryption in the context of cross-platform mobile apps (Cordova/Phonegap) ? Couldn’t this use case fit JS crypto reasonably well ?

    Comment by Nevermind — June 25, 2014 @ 4:32 am

    • That’s not browser crypto, but you can also talk to native extensions from HTML5 apps so still no need to replicate it in JS.

      Comment by Nate Lawson — October 28, 2014 @ 1:49 pm

  3. I’m confused by your dislike of the PCI avoidance scenario. Even forgetting about PCI, doesn’t RSA encrypting in the browser (which seems pretty safe, since there’s nothing secret to be exposed, even if there’s a bug in the encryption code), and decrypting somewhere in the backend avoid having the CC number in the memory of the web server? Which would prevent the recent Target/Home Depot attacks? Is it just that the idea that, “oh, we have malware reading our memory, but it’s encrypted so we’re ok”, is crazy?

    Comment by B — September 9, 2014 @ 2:32 pm

RSS feed for comments on this post.

Blog at WordPress.com.

%d bloggers like this: