5 ms·
JavaScript Cryptography Considered Harmful (2011)
- sl1ck731 7y agoIs using some other encryption for client interactions common vs just using TLS? I don't think I've seen anyone ever recommend any of these things. "You can't simply send a single Javascript file over SSL/TLS. You have to send all the page content over SSL/TLS." Is this a common problem in some way? It doesn't seem like a big deal unless you are trying to shave a few bytes off of your traffic.
- tptacek 7y agoIt was more common before than it is now; LetsEncrypt has probably killed the practice off. But what really motivated this was stuff like CryptoCat.
- nwallin 7y agoThe article is from 2011. Certs were expensive back then. People thought TLS was an unnecessary hassle, difficult to configure etc. There was an idea that you just do the really important parts (logins, authorizing fund transfers) over TLS and do the mundane stuff offer HTTP. (Static site assets) XSS was so rampant they gave it its own acronym. The natural extension of that was to do everything over HTTP and for the handful of objects that need to be secured, you just encrypt those ~100 bytes of important data. Then let's encrypt happened and all that went out the window.
- rubyn00bie 7y agoUhhhh... like what's the point of this? Like who is doing what they suggest folks are doing with JavaScript? Who isn't using SSL and who is rolling their own encryption layer? It seems like a clickbait rant more than something actionable or even really relevant. They even go on to say in the article you totally can do crypto "right" with JS it's just really hard. Isn't that known? Isn't that why we have libraries which are audited for security vulnerabilities by experts in the field? Isn't that true for literally _every_ language/runtime/vm ? I'm not saying JavaScript's number types and quirks aren't a huge pain in the ass but so is managing memory. /shrug just my two cents.
- geofft 7y agoThis is from 2011, when people (usually correctly) believed things like "SSL certificates are expensive," "SSL connections are expensive," "it's reasonable to host just the secure parts of your website on SSL," "if you only need authenticity and not confidentiality, it's better to avoid SSL if possible," etc. In the years since 2011, we could have implemented high-quality side-channel-resistant JS crypto libraries (plus added browser features to allow storing secret data that wasn't accessible to the website, auditing JS source, etc.), or we could have just deployed SSL everywhere. The world chose the latter, and it was a better choice.
- tptacek 7y agoThe article is talking about things like web mail providers that do in-browser OpenPGP to provide "secure email".
- tptacek 7y agoMuch as I'd like it to, this article will never die. I'm still convinced directionally of the argument I made here: browser Javascript cryptography is essentially cosmetic and provides none of the assurance that cryptography normally offers for client/server applications with clientside secrets. I think I could make a better, shorter, simpler can now than I did way back when I wrote this. Just to head off as many of the standard arguments I can remember occurring whenever this shows up on HN: * I'm talking about browsers-qua-browsers: while Javascript is not especially hospitable to cryptography the way, say, Rust is, it's not my claim that something intrinsic to Javascript is what makes cryptography hard. In particular: Node.js serverside applications and Electron clientside applications (with some caveats) are capable hosts for cryptographic features. * Yes, Chrome extensions do complicate the analysis for the browsers themselves (of course: application providers don't want to do Chrome extensions, because it drastically cuts down user adoption). The story with extensions is not as simple as for Electron applications. * No, WebCrypto doesn't make any of these problems better. WebCrypto provides primitives, but the interesting vulnerabilities in cryptosystems are in the joinery; a malicious server can still exfiltrate secrets even if you're using WebCrypto. * It remains Hard to effectively assure the integrity of whole programs delivered to browsers, because there are too many ways to update an instance of content-controlled Javascript. The standard answer of "we'll just hash the js files" has never been credible!
- TimTheTinker 7y agoRecently, I heard a smart person[0] make the argument that application-level encryption, even in the browser, is a net win. It's also worth mentioning that ProtonMail and 1Password both practice application-level encryption/decryption in the browser in their front-end web clients. App-level crypto in the browser certainly provides no added security to data transmitted over the wire, since (a) connections to back-end servers are already TLS-encrypted, (b) a breakdown of TLS implies the code running on the endpoint can't be trusted, therefore (c) assume data exfiltration when TLS breaks down regardless of other variables. I think this line of reasoning is just a restatement of your points above. However, depending on how the back-end is set up, a zero-knowledge end-to-end encrypted vault would be impractical and even dangerous to decrypt in the cloud prior to serving it. Hence, in an end-to-end encrypted app, the chain of trust in client connections is anchored at the static file servers, the JS code they serve, and the TLS connection itself, not application servers -- the less trust app servers have to have, the better. I posit that it's easier to secure a static file server and TLS endpoint than it is to secure application servers. Furthermore, client crypto protects servers from ever seeing (or having to store/hash/cache) the whole symmetric key. So client-side crypto can improve the security and trust calculus for server-side systems. In that case, a back-end breach of all but TLS endpoints and static file services would not expose user data. If anyone can explain what's wrong with or missing from this line of reasoning, I am all ears -- please do! [0] https://qconsf.com/sf2019/presentation/security https://qconsf.com/sf2019/presentation/security
- 3pt14159 7y ago> Any attacker who could swipe an unencrypted secret can, with almost total certainty, intercept and alter a web request. Not really. Modification risks exposure and some attacks are only possible after hours of compute time. For example if the HTTPS connection uses a cypher that's later found to be insecure then they can analyze the data pushed through the connection after the fact, but they can't intercept the now-closed connection. The NSA layers encryption for this purpose, and I don't really see the harm in encrypting with JavaScript as an additional layer in addition to HTTPS. Plus, there are many places where passive attacks are much more likely than someone that's actually going to change your JavaScript. For example, many organizations terminate HTTPS at the perimeter of their network in order to monitor employee actions on the web. Using JS to encrypt is going to keep your secrets safer there, though some would argue that it's hostile to the orgs that downgrade the protocol on purpose.
- geofft 7y agoMods, can we add (2011) to this? A bunch of the comments seem to be saying this advice doesn't make much sense in 2019, and in fact, it doesn't - it's written for a world where people are trying to avoid SSL if they can.
- Ajedi32 7y agoThis article is a little outdated. (2011; that should probably be in the title.) JS in the browser _does_ have a cryptographically secure random number generator now, for example (Crypto.getRandomValues) and a secure way to generate and store keys (SubtleCrypto.generateKey). A lot of the article's other concerns are still valid, but there are a few new standards on the horizon which could eventually fix most of those and make cryptography in the browser viable, such as the Web Package standard. The Signed HTTP Exchanges standard's section on binary transparency is especially interesting for this use case: https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#name-binary-transparency https://wicg.github.io/webpackage/draft-yasskin-http-origin-...
- s_tec 7y agoYou can't roll your own TLS replacement using Javascript, because you need some way to deliver that Javascript to the browser in the first place. If you don't use TLS for that, you're doomed. Sure. On the other hand, that's a pretty narrow definition of "Javascript Cryptography". The article overlooks a bunch of other useful cryptographic things you can do in the browser, like end-to-end encrypted messaging. You can't lose a giant database of customer data if you don't have a giant database of customer data sitting around. Javascript can encrypt stuff before it even leaves the browser. If you build your service this way, an attacker would have to carry out an active attack that injects bad code into your Javascript bundle. That's much harder than stealing a database, and even if it works, it can only compromises the users who log in during the breach. So, no, the right kind of Javascript Cryptography is actually quite beneficial.
- iudqnolq 7y agoYou're skipping over the part about users having to recheck what you serve them every request to see you haven't added a backdoor. Not sure how much security people being able to look at and pin versions with traditional software they build adds, but probably nonzero.
- s_tec 7y agoRight, and the only solution is to audit and compile all the code running on your computer, including firmware. Otherwise, you have no idea what your computer is really running. In the real world, most people run pre-built software, which is worse than this ideal. I agree that browser Javascript is worse still, but it's still better than sending secrets to a centralized server somewhere. Security is a spectrum, not a binary on/off thing like this article tries to paint it. Things can still be helpful, even if they aren't perfect.
- iudqnolq 7y agoI agree completely. I didn't intend to say you were wrong, just that you didn't mention an important consideration.
- ravenstine 7y agoCryptography in JS is useful when you have a secure channel and you only want the plaintext available to one party. (ex. a secure file store or encrypted mail server)
- dang 7y agoThread from 2014: https://news.ycombinator.com/item?id=7903720 https://news.ycombinator.com/item?id=7903720 2013: https://news.ycombinator.com/item?id=5123165 https://news.ycombinator.com/item?id=5123165 Discussed at the time: https://news.ycombinator.com/item?id=2935220 https://news.ycombinator.com/item?id=2935220
- kerng 7y agoThis is not the best article, it fundamentally sees security as a black and white concept. Whereas its shades of gray and levels of defense.
- danShumway 7y agoFrom a purely technical perspective, this article raises multiple valid points. From a practical perspective, there can be legal and logistical benefits to not knowing what your customers are doing. I think articles like this get treated like they're referring to a broad category of activities, or making very broad statements, when in fact they're talking about a very narrow aspect of security. And to be fair, people do treat Javascript Crypto like it's the same thing as normal, native E2E encryption, so maybe that pushback is sometimes necessary. But this isn't a binary, black-and-white principle. JS crypto is problematic in environments like the web because it is very hard to validate or pin the code that is sent to your browser (and for a few other reasons). This means that E2E crypto is not a good way of protecting yourself from a malicious provider. JS crypto does not remove your need to trust your host, and to trust your host's security. It does not follow the E2E crypto has no uses at all on the web. It just means you have to be open about what benefits it does and doesn't provide. It isn't a silver bullet that will protect you everywhere.
- avmich 7y agoInteresting that author seem to omit the possibility of PGP functionality available locally in the browser - as, say, a bookmarklet. Surely websites aren't designed in a way to take advantage of that, but I still don't see in the article a good argument why that is impossible - given that the local code is a carefully written (e.g. Stanford crypto library seems to be a good example of crypto JS code).
- motohagiography 7y agoInteresting to relitigate this every few years. We can sum it up every time with, "private/secret keys accessible to browser means trusting the users browser." the details are superfluous. The relevant xkcd on this is this one: https://xkcd.com/2217/ https://xkcd.com/2217/ Where "check my math" means the same thing. The browser isn't trustworthy.