Hacker News new | ask | show | jobs
by jarrett 4387 days ago
It's not clear to me if the author is endorsing the use of browser crypto in any particular scenario. Regardless, probably the most common reason for wanting browser crypto is to protect the data before it hits the server, thus protecting against a malicious or compromised server.

For example, consider a web-based mail client. You want to send an encrypted message, say via PGP, and you don't want the server to be able to read it, even if the server is evil. You'd like to be able to do the PGP encryption 100% in-browser, with no browser plugins or extensions necessary.

I think that's the most common category of use-case for browser crypto. Unfortunately, it's one where browser crypto plainly doesn't work. The whole point here is to defend against an evil server, but if the server is evil, it will send you evil crypto JS. TLS doesn't help you. Nobody's impersonating the server or altering the JS file in transit. You're getting an authentic copy of the JS file from the real server. It just happens to be an authentic copy of an evil JS file.

Given that, what can you do with browser crypto, practically speaking?

3 comments

It still might protect you if you won't access server while it's compromised. It protects you from someone just hacking your server, downloading all the data and getting away.

Also you might serve files that do the encryption from different server that's smaller, better protected, more stable, that less people have access to.

> It still might protect you if you won't access server while it's compromised.

The end user can't know when that's the case.

> Also you might serve files that do the encryption from different server that's smaller, better protected, more stable, that less people have access to.

That doesn't provide any assurance to the end user that the JS isn't malicious.

Remember, "compromise" doesn't just refer to a drive-by hack. The site operators themselves may become compromised (or start that way), and deliberately serve malicious JS. Users can't know when that's the case. When it is the case, the strategy you suggested offers no protection, because the "more secure" JS server is still under the control of the bad actor.

>> It still might protect you if you won't access server while it's compromised. > The end user can't know when that's the case.

Yes. I didn't say that user can know if he is protected. Just that he is when this condition is met.

> Remember, "compromise" doesn't just refer to a drive-by hack. The site operators themselves may become compromised (or start that way), and deliberately serve malicious JS. Users can't know when that's the case. When it is the case, the strategy you suggested offers no protection, because the "more secure" JS server is still under the control of the bad actor.

Didn't you just do what OP criticizes? I said it has value in some scenarios assuming some threat model and you countered by showing that it doesn't protect you in some other threat model. When you don't trust the third party the only way to protect yourself is never rely on what they control. Especially never run their software on your machine in a way that has access to your secret data. In that scenario any type of encryption other than built in the browser binary (not supported? risky?) or better yet outside of browser (cumbersome) is pointless.

> > It still might protect you if you won't access server while it's compromised. > The end user can't know when that's the case.

This is the entire point of the article. You can't know if it's the case, you can't either with any software distribution. When you type 'apt-get install opensshd', how do you know if you're getting the package from an uncompromised server?

You just have to trust that the public keys you got are the right ones, and their private keys have not been stolen.

So what the author is saying is that regarding that aspect web crypto is at roughly the same level.

The big problem of course is that there is evidence that the whole CA system is much less reliable than the old GPG signing party system.

> When you type 'apt-get install opensshd', how do you know if you're getting the package from an uncompromised server?

If you don't take any steps to verify the integrity, then you don't know.

The big difference, as I see it, is that the JS code gets served over and over again to the same clients. Every time you visit the website, it can load a new version of the JS.

Even if you do verify the integrity of the package, then you still can't know for absolute certain that the package maintainer hasn't somehow exposed their private key or been otherwise compromised. You have to trust them.
If the package maintainer has exposed their private key, and yet the package itself in intact, what harm is there (at the moment)? With the key compromised, you could have been MITMed, but you weren't. You could be MITMed in the future, but that's a problem for another day.
Server-side crypto protects you from someone just hacking your server and downloading the data too.

Serving from a smaller and more protected server is interesting, but you'd have to serve at least the HTML as well as every piece of JavaScript (not just the crypto) which doesn't leave too much room for other stuff. And why not just do the crypto server-side on that smaller, more protected server then?

> but you'd have to serve at least the HTML as well as every piece of JavaScript (not just the crypto

You are right.

> which doesn't leave too much room for other stuff.

Well... HTML and JS can be light and static. Backend stuff is what might require multiple servers, databases and lots of people involved.

> And why not just do the crypto server-side on that smaller, more protected server then?

Because you'd have to pass all of the data that you wan't to secure through it. Besides server-side crypto is surely more complicated and would need more people involved especialy with large volume of data than just serving static files.

lol, This is exactly what I was trying to stop people from doing! I'm not endorsing or damning it--I'm talking about it sensibly and objectively so people can learn to use it properly.

Please read the article again carefully. I think you'll find the answers to your questions.

While you might be formally correct, your criticism still seems about as sensible as criticising someone who said "a tank made of paper sheets is not secure" because they failed to specify a threat model. After all, such a tank would be secure against a paralyzed attacker without weapons.

Yes, it is important to be aware that security is always relative to a threat model, and at times it can lead to confusion when threat models are not made explicit. That does not mean, though, that it's necessarily wrong to imply a sensible threat model in a given context, and to just call something "insecure" without any further explicit qualifications if it does not protect against a reasonable minimal threat model that essentially everyone essentially always has to face.

Also, it's questionable whether you can call the NSA's mass surveillance a passive attack, given that QUANTUM INSERT exists and was used, in order to attack foreign communications infrastructure.

This is also precisely the problem I was trying to avoid by introducing formality.

Is it like saying that a tank made of paper sheets is insecure, or is it like saying that a heavily-armored tank is insecure (against a nuclear weapon)?

It is never okay to omit important information like the threat model in cryptography. That information is essential to the system's analysis.

> Is it like saying that a tank made of paper sheets is insecure

Yes, I'd say it's more like that one. The technology is insecure against threat models it is almost certain to face.

> or is it like saying that a heavily-armored tank is insecure (against a nuclear weapon)?

No, I don't think it's like that one. A tank could realistically participate in a nuclear conflict, but that's not necessarily what a tank is intended for. Whereas, JS crypto is presumably intended to protect users when the remote server can't be trusted. (What else would it be for?) It can't offer such protection.

What about a secret message web widget on a shared computer that uses localstorage as a database and requires the recipient to enter a password to reveal the message, or an offline diary app made with node-webkit that encrypts diary entries? There are lots of uses for JS crypto in cases where information will never leave a local computer. I know that's not what you were saying, but I think it's important to realize that JS has gone beyond remote delivery at this point.
The problem is that with the in-browser use case, which is what this whole discussion is about, the code being executed locally came from a remote source. For all of the reasons that Monsanto and the others name it is impossible to ensure that the code does what it claims to. So even if all of your data is stored locally, you have no strong way to ensure that the code that is performing the cryptographic functions is not secretly compromised by an attacker so that, for example, it sends your data in clear to some remote server.
Even though it often isn't spelled out, this is mostly about content-controlled JS loaded from the web, though the language itself also has its problems. And security-wise that app would not be better than one that stored the messages on a server, which only allows you to read them back when you provide the password.
> so people can learn to use it properly.

That's the part to which I'm objecting. As I asked above, what is the proper use of JS crypto? What real-world application do you have in mind where JS crypto's level of security is adequate?

Packaged in a signed browser extension is a good start. Or packaged in a signed desktop app that runs JS to drive the UI (xulrunner, node-webkit, ...).

In general, anywhere you aren't basically doing what amounts to an eval() on an external resource (so packaging everything locally, aggressively filtering XSS attacks) can be a good use of JS crypto.

I don't think JS crypto itself is the issue. I think the issue is more pulling your code from an external, ultimately untrusted source. You can do this in many languages, and it's equally a Terrible Idea in all of them. Granted, some things auto-update and can verify an update via a packaged public key, but the model of continuously downloading code on each run, while easier on app developers, is a ticking time bomb for crypto.

> Packaged in a signed browser extension is a good start. Or packaged in a signed desktop app that runs JS to drive the UI (xulrunner, node-webkit, ...).

Those are probably acceptable in principle. I should have been more specific: I was referring only to the scenario wherein the webserver provides the JS.

Well, now that we have WebRTC, peer-to-peer data transfer is possible in the browser. Perhaps you could imagine a p2p scenario where browser crypto is useful?