8 ms·
Client side cryptography is almost always about providing a solution that doesn't require server trust. This article mentions end-to-end encrypted messaging, f
by moxie 13y ago
Client side cryptography is almost always about providing a solution that doesn't require server trust. This article mentions end-to-end encrypted messaging, for instance, which provides the nice property that not even the messaging server can read the message contents.
The problem with webapp-based javascript cryptography is that if the crypto code is delivered by the server, then the client is back to trusting the server. The server operator, an attacker who can compromise the server, or an attacker who can compromise the SSL connection from the browser to the server can modify the JS to spray plaintext wherever they'd like.
Basically, the JS crypto is reducible to the strength of the SSL connection. Anyone on the other end of the SSL connection, or anyone who can break the SSL connection, can get your plaintext. This makes the JS crypto nothing but overhead. It's just hand-waving at that point.
This is not a theoretical weakness. This is exactly happened to both Lavabit and Hushmail. The experiment has been tried and the hand waving didn't amount to much. There's no need (and no excuse!) to try it again.
- bennyg 13y agoIs there no way to independently verify that a) the scripts are what they are, and b) that the values change before going to the server?
- Judson 13y agoI have seen people point to using plugins to verify assets delivered by the server, but at that point, why not just do the crypto with the plugin.
- Jach 13y agoThe benefit of a plugin to verify assets is that it can work with other things besides the crypto lib. As your sibling comment mentions an attacker could deliver other JS that just traces your input or something different. Well, a user could ask a plugin to say "Hey, track the JS on this page. Alert me if any of it changes, any of it is removed, or any new JS is added." After an alert, the user can see a diff, decide to trust the new set of JS (maybe it was just a jquery update), try and run the old set instead, or don't run anything. A cool plugin could even connect with a repository of peer-reviewed changes so that non-technical users can still safely use it, so they might see "This change to blah.js has been marked as OK by X respectable users (see reasons)" or "It's a trap! Foobar.com has been compromised by (feds|anonymous|gary)."
- tptacek 13y agoHow exactly do you use a plugin to verify the state of a Javascript runtime? You can't just verify assets; you need to verify the current bindings of every function relevant to your crypto code.
- lambda 13y agoBasically, the way JavaScript security currently works, browsers trust all code sent from the server you are communicating with to manipulate everything coming from or going to that server. You could talk about ways to independently sign and verify some crypto primitive or crypto library and be confident that it was being used to encrypt your communications appropriately. But this wouldn't help at all. There's nothing stopping the person controlling the server (or MITMing your connection to it) from adding additional code that scrapes the text input boxes, or captures keystrokes, or simply follows the appropriate variables down to the ones which contain your text before its sent off, and then sending that back to the server in an XMLHTTPRequest, via a websocket, via loading an appropriate image, or even hiding it quite well among the timing of when requests are made to the server. The fundamental problem is that the code comes from the same person providing you the connection, and it is updated every time you use the page, so it offers no additional security above just trusting them directly. If you want good crypto and good security, you want stable client side software from a trusted source, and a different source routing your traffic, so that both of them would have to be compromised to compromise your data. Now, there may be one small advantage in client-side crypto. That's if due to problems with TLS (in particular, the version and protocols supported by your browser), there are TLS weaknesses that can be exploited, like a MITM attacker forcibly downgrading your crypto to a weak algorithm that allows them to eavesdrop but not forge content. In this case, stronger crypto implemented in JavaScript could be used to keep your data confidential. But this is a very narrow corner case, that's probably better handled by fixing browsers so they aren't prone to protocol downgrading attacks.
- notwhyships 13y agoThis is a deck by Ben Adida (formerly of Mozilla, where he led the Persona project and now at Square) explaining how that argument is reductionistic. https://docs.google.com/presentation/d/1bLBb0EIJ0cuoAhsmI1XLRj1QfGlGTfofJwlemqaP-hM/edit?pli=1#slide=id.g665e5ab7_0_5 https://docs.google.com/presentation/d/1bLBb0EIJ0cuoAhsmI1XL...
- rosser 13y agoCan you please help me find even an argument in that deck, let alone any refutation? Did I get an incomplete deck, perhaps? The version I'm seeing stops at slide 22.
- notwhyships 13y agoThere are 22 slides. It's admittedly terse (it was part of a presentation Ben Adida gave at the first Real World Cryptography workshop). However, I'd suggest reading the deck again, and while you do asking yourself, does JS crypto provide any security beyond what SSL does? And, can JS crypto make sense as part of a defense in depth/layered security approach?
- bmm6o 13y agoHe's presumably referring to slides 17-20. It essentially boils down to "JS crypto in the browser is better than nothing".
- rosser 13y agoBut it's not — at least not necessarily. That's the problem. It creates a potentially incredibly dangerous false sense of security, and nothing in the deck refutes that, or even argues against it.
- derefr 13y ago> Basically, the JS crypto is reducible to the strength of the SSL connection. Anyone on the other end of the SSL connection, or anyone who can break the SSL connection, can get your plaintext. This makes the JS crypto nothing but overhead. It's just hand-waving at that point. This is true. However, you can say the same thing about, for example, retrieving an ISO of Ubuntu. A cryptosystem is as weak as its weakest link, and that weakest link may of course be the way you downloaded the cryptosystem in the first place. But once the cryptosystem is in place, you don't have to trust SSL any more. By default, webapps are always retrieved from the server for every new session, but application manifests and offline storage are an effective means of avoiding this. You can build a webapp that is only ever downloaded once, and from then on loads its own code from the filesystem; and which verifies new "releases" of its own source using whatever crypto it likes before overwriting the client-side stored copies of itself. Neither Lavabit nor Hushmail implemented this sort of application-release policy, but they easily could have.
- utnick 13y agocryptocat accomplishes this by distributing itself as a browser extension
- DanBC 13y ago> You can build a webapp that is only ever downloaded once, and from then on loads its own code from the filesystem; and which verifies new "releases" of its own source using whatever crypto it likes before overwriting the client-side stored copies of itself. But if you don't trust Hushmail they could force a back-doored update onto you.
- derefr 13y agoAt that point you've got "well, that's not worse than anything else, then" security. The NSA, for example, could MITM your computer's connection to Ubuntu's update servers, FISA a sysadmin for a copy of their package signing key, and inject a "critical security update" only for you. Auto-update systems are suspicious as a whole, now, and should only be trusted in general as a compromise to convenience, and the statistical unlikelihood of you being attacked.
- taway2012 13y agoHi moxie! First off, I agree with what you said. But I had a question about your observation. Don't the same problems apply to any autoupdating system (including smartphones, tablets and computers)? I've posted once before asking that Chrome and Firefox implement certificate pinning APIs for extensions/addons so that MITM SSL attacks can be detected. Maybe they'll see it now. :)
- ww520 13y agoClient side Javascript cryptography is about equivalent to SSL; however, it doesn't mean it's not worthwhile to do crypto on the client side. At least the computation load is distributed to all the browsers involved, thus lessen the demand and load on the server.
- tptacek 13y agoYou can't securely load crypto into a browser without SSL, so the server is bearing that load anyways. All you're doing is adding additional load on the clients.
- ww520 13y agoGiven a client side crypto implementation with SSL as the delivery mechanism, the only load on the server is the content delivery and the SSL computation itself. Any of the application-specific crypto load can be done on the browser instead on the server. Let's say the app is encrypting 1meg Excel file and 100K people are using it. I would rather letting the browsers do the work than beef up the servers to do the encryption on server side.
- JoachimSchipper 13y agoThis article has long scrolled off the front page, so just a quick reply: modern crypto is fast. Look up the speed on AES-GCM with AES-NI, PCLMULQDQ; on a modern multicore server, your 100GB can be encrypted in a couple of seconds. (Or rather, the crypto isn't remotely the bottleneck.)
- cortesoft 13y agoWhile these known issues are true, and still need to be worked out, I don't think stopping all work on crypto in the browser is the best course of action. There are technical ways we could mitigate these vulnerabilities (signing of JS downloaded from a site, for example). Maybe having crypto in the browser become a thing is the way that these features get the support to be implemented.
- nwh 13y agoIt always comes down to this; would you prefer security, or just something that makes you feel fuzzy? Crypto in JavaScript only gives the latter.
- nlacasse 13y agoI disagree. Javascript cryptography can provide real security, it's just important to keep in mind what is being secured, and where the vulnerabilities are. Currently, js crypto is vulnerable in that its difficult to verify that the js a browser is running is the intented code. Every day, millions of people are sending sensitive data over very insecure channels like email and DropBox because secure tools like PGP are to difficult for them or their friends to use. Clearly some security is better than none, as long as the limitations are known.
- tptacek 13y agoThis is like saying a sign that says "attackers keep out" provides real security, as long as you keep in mind that it only works if attackers obey the sign. After all, Dropbox doesn't have an "attackers keep out" sign!
- azakai 13y agoNo, it's more like an imperfect lock is still more security than no lock at all on your door.
- 13y ago
- nlacasse 13y agoThanks for the reply. Opal requires as little trust as possible, but you are correct that some server-trust is required at the moment. I hope that apps like Opal will encourage more progress on browser/javascript cryptography. The W3C crypto spec is coming along nicely, and things like Content Security Policy address some of the concerns about delivering secure javascript. One nice thing about web-apps is that they are by-default open source, and browsers are bundled with all sorts of diagnostic tools. Anybody who worries that their data is being "sprayed" can just open the network tab and see exactly what is being sent over the wire. Obviously we don't expect many users to do this, but it's one way to enforce our honesty until better solutions exist.
- tptacek 13y agoI think building something you know to be insecure and providing it to your user along with an assurance that your service takes their security seriously is a poor way to motivate other people (here, browser vendors) to build that security for you. Meanwhile: the network tab thing only does anything if you do it every time and validate all the content. Nobody does this, ever.
- moxie 13y ago> Opal requires as little trust as possible, but you are correct that some server-trust is required at the moment. Unless there is some other mechanism at play here, it requires full server trust. > I hope that apps like Opal will encourage more progress on browser/javascript cryptography. The W3C crypto spec is coming along nicely, and things like Content Security Policy address some of the concerns about delivering secure javascript. I don't think you can just cross your fingers and hope for the best here. Whether or not it's coming along nicely is debatable, but one way or another the W3C crypto API has no bearing at all on this problem. You're talking about implementing a "secure" service using a mechanism that is known to be insecure. For a mechanism like this to function correctly, it would likely require substantial changes to the way the web browser works that aren't currently on anyone's roadmap. Again, this is not a theoretical problem. Two companies have done the exact same handwaving that you are doing now about users watching tcpdump to verify their traffic, and both of them were functionally destroyed when that handwaving didn't work. It doesn't seem prudent to knowingly put users (or yourselves!) into that position again.
- IgorPartola 13y agoSo the question then is when will browsers provide access to crypto libraries as a built-in JS API? Clearly, the browser already requires crypto to function. Why can't we standardize a way to access it from the runtime and provide a way to run code against it in a sandbox that would be impervious to things like wrapping one JS function in another? On top of that we would need some code delivery system with built-in trust verification. This way you could load an up to date copy of PGP written in JS and verify that this code comes from a source you trust. Then again, this is starting to look a lot like a secure package management system and downloaded software vs the continuously updated web apps we have today, so it might not be worth reinventing the wheel...
- tptacek 13y agoHow exactly does it help to provide access to built-in crypto libraries through a JS API? The code that manages those crypto primitives is still content-controlled Javascript.
- IgorPartola 13y agoIt doesn't (though one might argue that as a result we will see much fewer JS implementations of AES coming out). What I am talking about is a better way to distribute the code, the ability to verify the code, the ability to sandbox it, and a proper secure crypto implementation to rest this on. Basically, I want the contents of GMail messages (ones I compose and ones I read) to be rendered in a sandbox to which the rest of the page has no access. Moreover, I want to get the code that makes the sandbox tick to not come from Google, but from a third part I actually trust. Once again, this starts looking a lot like normal downloaded apps with package signing, and less like the web. I am not certain there is a middle ground between the two that provides both security and convenience.
- ptoomey3 13y agoI've gone back and forth in my own head about this argument over the years, and I'm still not entirely sure where I come down. But, that said, I have seen the following problem several times, and it seems like client-side crypto provided a reasonable solution. Challenge: I have a client (web browser) and I have a back-end server (sitting deep behind several layers of intermediate servers of varying degrees of trust) and these two entities need to exchange some sensitive piece of information (a credit card number, etc). How do I transmit this information (either from client to server or the reverse)? Problems/Assumptions: Let's assume I trust the front end server explicitly to serve fully server-controlled data. Obviously, if we don't trust the server serving me the JS it is all for not. Now, let us also assume that, although my front end server is trusted, it, as well as all of the intermediate servers may accidentally log data that flows through them. In other words, we assume that if I pass a plaintext credit card number over a trusted SSL connection to the server, it, or any of the intermediate servers on the path to the trusted back end server, may accidentally log the sensitive data. How do you solve that problem? Solution: You could use client-side crypto to create an end-to-end channel that transmits the sensitive data to the back end server. So, yes, the above solution assumes a fully trusted front end server. In this case, the client side crypto is more to protect the service provider than for the user, but it does seem to provide some sort of "existence proof" in so far as it is a problem that exists in the real world, is made better using client-side crypto, and doesn't seem to have many alternative solutions that provides the same assurances. P.S. This is more or less what BrainTree does with their client-side encryption for credit card processing (https://www.braintreepayments.com/braintrust/client-side-encryption https://www.braintreepayments.com/braintrust/client-side-enc...). In this case, the front end server needs to be trusted, as it is serving up the public key to bootstrap the whole system. But, if we assume the server is trusted (even without client-side crypto we have to assume this for any security) then this approach mitigates the problem of logging credit card data by accident. Now, maybe this use case is the only legit use of client-side crypto. But, it does make me take pause before dismissing the approach entirely.
- dsl 13y ago> I've gone back and forth in my own head about this argument over the years, and I'm still not entirely sure where I come down I think you are unfairly reframing it as some sort of debate. It's like not being totally decided on if you should log into your server over telnet from a coffee shop. Even if you don't see the weakness, attackers do.