7

There are lots of older articles1 on why in-browser crypto is a bad idea. Most are summed up via: http://bitwiseshiftleft.github.io/sjcl/

We believe that SJCL provides the best security which is practically available in Javascript. (Unforunately[sic], this is not as great as in desktop applications because it is not feasible to completely protect against code injection, malicious servers and side-channel attacks.)

It seems the biggest problem they mention is that an attacker could serve you bad javascript that the browser executes because XSS is so common.

Between TLS and an extremely restrictive Content Security Policy, is this still an issue and therefore in-browser crypto a bad idea?

The goal of the encryption is not to replace TLS. It is being used to encrypt documents before they reach the server so only the sender and recipient can read them.

1:

  • It is and always will be a bad idea because you need TLS to ensure that the browser crypto js is authentic. And if you have TLS you don't need js crypto – Neil McGuigan Aug 8 '16 at 17:46
  • I clarified the question. The encryption I want is not to replace TLS. It's for encrypting the content so it cannot be read by the server. – erik Aug 8 '16 at 17:56
  • It is still a bad idea because the server admin can always change the js crypto lib and read the "client encrypted" info on the server. You need to use an open source client-installed program, which is not under control of the server admin – Neil McGuigan Aug 8 '16 at 18:10
  • 1
    @NeilMcGuigan: generally server admins can do whatever they want to ruin security, but if the keys aren't stored on the server, how can said admin read client-encrypted data? (prompting+PBKDF, indexedDB, crypto.subtle, etc) – dandavis Aug 8 '16 at 19:03
  • 2
    It's how LastPass does it. At the end of the day the user has to trust that the client executed script hasn't been modified. – SilverlightFox Aug 9 '16 at 13:01
11

I've been hoping someone would ask about this topic, i've been doing a lot of research in the area.

You are correct that most of the points in javascript-cryptography-considered-harmful are outmoded by newer browsers. Aside from the obvious issue of someone compromising the server, which is a separate issue and presents a problem to TLS as well, the main points are now "fixed":

  • window.crypto.getRandomValues() uses a real CSPRNG
  • HTTPS is common and much cheaper now than in 2011
  • CSP's integrity and nonce <script> attributes can secure script delivery to make sure what's running is expected
  • SJCL is years more mature than in 2011, and no major issues are outstanding
  • malleable runtimes don't matter if you don't have XSS, which CSPs are now good at stopping

Furthermore, we now know that HTTPS is not an absolute guarantee of privacy (snowden/heartbleed/crime/breach/etc), but proper end-to-end encryption is. We can also now implement fairly robust, battle-tested, and secure libraries, backed by a more secure JS runtime than what was offered in 2011; "use strict" widely supported, a CSPRNG, binary structures, web workers with sealed runtime environments etc.

Those are updates to the main points, but if you have concerns about other aspects of client-cryptography, i'll be happy to address them.

Of course, nothing is perfect:

  • really old browsers still have issues or can't run new code securely
  • user-added extensions can run whatever code they want
  • malware can replace the whole browser with something sinister, or steal data pre-encryption
  • phishing can trick the user into using something besides your safe site.

In short, i think post-snowden, we should try to keep plain private data off servers wherever we can help it, and solid end-to-end encryption, done right, greatly enhances the privacy of your users and the security of their content.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.