1

Earlier this year, I was asked to evaluate using JavaScript to encrypt sensitive information in the user's browser before sending it to our server. While my first response was "ask an expert", my boss was adamant so I went ahead and researched expert opinions on the topic as well as I could. Based on that research I came back to him with a resounding "no expert thinks that's a good idea" and was able to convince him, but I wasn't able to actually specifically answer some of his rebuttals for REASONS it was a bad idea. Specifically the main reasons I found for JavaScript in-browser encryption being bad were:

  • Just use TLS in the first place, it's 100% certain to be better
  • JavaScript doesn't offer cryptographically secure PRNG
  • Any Man-In-The-Middle attacker would just modify the encryption code, rendering it useless

However, the specific use-case I was investigating mitigated those:

  • We were already planning to enforce TLS, with the JavaScript portion only intended to cover for future TLS vulnerabilities
  • We would generate an RSA key-pair elsewhere and send the public key with the encryption code, rather than needing the client to generate or send keys of its own
  • Although it wouldn't protect against an attacker which could modify our javascript, we could still protect against vulnerabilities that allow only READING messages

I wasn't able to come up with a real answer to the last argument in particular, and could only fall back to "overwhelming consensus". I can think of some POSSIBLE arguments, but wasn't able to definitively support them:

  • Encryption inside of TLS adds no value in the first place
  • Read-only vulnerabilities in TLS aren't realistic, any crack would inherently allow modification as well
  • Even without modifying the original encryption code, an attacker could inject JavaScript in a different manner and prevent encryption that way
  • It could add a modest amount of security, but the effort and knowledge required to create and maintain it would be prohibitive

TL;DR: The main arguments I've seen against JavaScript encryption are 1) use TLS instead and 2) JavaScript doesn't generate secure keys. If TLS is also used, and keys are generated elsewhere, does JavaScript encryption start adding value?'

Note: In response to a couple comments, the use-case here is NOT end-to-end encryption; the server needs to, at least in some situations, read the original data.

  • 1
    Related: [Problems with in Browser Crypto](https://security.stackexchange.com/questions/133277/problems-with-in-browser-crypto) – Arminius Dec 22 '17 at 15:36
  • 2
    Crypto inside the browser has at least one use that isn't covered at all by TLS: when you want to protect the user data from being seen by the server. Real life example: https://protonmail.com/ – Najkin Dec 22 '17 at 15:45
  • As riokmij says, only when you want to make sure that your message doesnt hit the server being plain-text. – Aria Dec 22 '17 at 16:16
  • 3
    @Riokmij Except that the server could easily decide to send JS to your browser that would allow it to read your data after you log in. That's the real issue with that implementation; you still have to trust the server. – Ajedi32 Dec 22 '17 at 16:32
  • Thanks to the Web Crypto API, we now have a way to generate cryptographically-strong random numbers in Javascript. See https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues. – mti2935 Dec 29 '17 at 18:33

1 Answers1

1

Obviously, the development of the Web Crypto API indicates that there is a future for encryption in Javascript on the internet. (Or at least the W3C believes so!)

You can now generate secure random numbers and perform cryptographic operations efficiently, so you can use it for cases like you have described. (Another example could be to protect you in case of a passive observer in a position like Cloudflare.)

As you've pointed out, you still need TLS to provide integrity, for a failure there would allow an attacker to modify/inject malicious javascript. However, your proposal might mitigate concerns like BREACH, CRIME, and similar vulnerabilities. (Depending on your implementation, it might also help in the case of issues like Heartbleed.)

One problem you haven't considered is ensuring that your cryptography is adequately well-implemented that it doesn't open you up to new attacks. Cryptography is not a panacea, and if done poorly, it can make life worse. (For example, it might lead to new timing or ciphertext size-related attacks.)

David
  • 15,814
  • 3
  • 48
  • 73