Live data from Hacker News

End-to-end encryption in the browser

blog.excalidraw.com

81–90 of 112 posts

Re: End-to-end encryption in the browser

#81

const encrypted = await window.crypto.subtle.encrypt( { name: "AES-GCM", iv: new Uint8Array(12) /* don't reuse key! */ }, key, new TextEncoder().encode(JSON.stringify(content)) ); This looks wrong. The iv should be a randomly generated string that is only used once. I'm not super familiar with modern Javascript, but I think you're just initializing a bunch of null bytes. Honestly, I feel like whoever designed AES int…

Well on the site it was said "We encrypt the content with that random key. In this case, we only encrypt the content once with the random key so we don’t need an iv and can leave it filled with 0 (I hope…)." Anyone think that is a good idea?

It's a good idea if you encrypt with the same key _once_ — you can avoid attaching nonces to your ciphertext (less code and data), and have only 16-byte key in the URL.

In fact, using a random IV with AES-GCM is not exactly safe: 12-byte nonce is too small to avoid collisions with many encryptions. The recommendation is to not encrypt more than 2^32 messages with the same key if you use the random nonce.

Re: End-to-end encryption in the browser

#82
post #17

I appreciate the effort, but this is one of those cases in which there isn't much security added by encryption. If I assume the website owner is malicious (or subverted by powers that be), I cannot trust the JS code provided by the website. Key disclosure is as trivial as one line hidden somewhere in megabytes of JS code delievered from the server. Which makes "end-to-end" part nearly meaningless.

All JS is executed in the browser. If the malicious site wanted to steal the data, it must send the key to the server.

With enough inspecting, debugging, and network watching you would be able to see what they're doing and how.

While I agree you can obfuscate this in the JS payload, it doesn't make e2e encryption in web apps "meaningless". It would just take one user doing some due diligence to expose the malice.

Re: End-to-end encryption in the browser

#83
post #47
post #40

Earlier quoted context omitted.

I can build a native app from the codebase myself. I can be sure that a native up won't change in-between launches. > In any E2E context you have to trust the client code. I don't have to trust code which is continuously being delievered from the server. This is an intractable problem.

Others have said it's open-source. Build it yourself, inspect what your browser downloads, hash and compare like normal.

It doesn't even have to be open-source. Any JS that will get run is handed to your browser and you are able to inspect it.

Re: End-to-end encryption in the browser

#84

Earlier quoted context omitted.

yeah, this. Having the key in the url seems insanely insecure to me.

Why? It makes it easy to share a sketch with someone else while still preventing the server from decrypting the data. Anything stored in a location hash (after the # symbol) does not get passed to the server. The threat model the author tried to work around is not the user dumbly compromising their own work. The author wants to prevent proprietary and PII data from being stored on their own server. End-to-end encrypt…

> Why? It makes it easy to share a sketch with someone else while still preventing the server from decrypting the data. Anything stored in a location hash (after the # symbol) does not get passed to the server.

I'll hit the URL bar and hit control-C. That's way better than any javashit which wants to touch my clipboard.

Copying the current URL also copies the key in that case. Now I'm accidentally sharing my encryption information with another user.

Re: End-to-end encryption in the browser

#85
post #82
post #17

I appreciate the effort, but this is one of those cases in which there isn't much security added by encryption. If I assume the website owner is malicious (or subverted by powers that be), I cannot trust the JS code provided by the website. Key disclosure is as trivial as one line hidden somewhere in megabytes of JS code delievered from the server. Which makes "end-to-end" part nearly meaningless.

All JS is executed in the browser. If the malicious site wanted to steal the data, it must send the key to the server. With enough inspecting, debugging, and network watching you would be able to see what they're doing and how. While I agree you can obfuscate this in the JS payload, it doesn't make e2e encryption in web apps "meaningless". It would just take one user doing some due diligence to expose the malice.

It does not work this way if this attack is targeted on a very few users and it's trivial to serve a different scripts to a different users.

Re: End-to-end encryption in the browser

#86
post #47
post #40

Earlier quoted context omitted.

I can build a native app from the codebase myself. I can be sure that a native up won't change in-between launches. > In any E2E context you have to trust the client code. I don't have to trust code which is continuously being delievered from the server. This is an intractable problem.

Others have said it's open-source. Build it yourself, inspect what your browser downloads, hash and compare like normal.

How do you hash your browser downloads? Also you need to perform that on every request. It should be possible with additional addons, but definitely not out of the box.

Re: End-to-end encryption in the browser

#87
post #61
post #17

I appreciate the effort, but this is one of those cases in which there isn't much security added by encryption. If I assume the website owner is malicious (or subverted by powers that be), I cannot trust the JS code provided by the website. Key disclosure is as trivial as one line hidden somewhere in megabytes of JS code delievered from the server. Which makes "end-to-end" part nearly meaningless.

Are there any current browser standards for validating that the served JS is ‘safe’? I can see such a thing being also useful for applications like ProtonMail, for example? What about something like a browser extension that queries an audit server for a list of signed hashes of ‘safe’ JS? - Well-known code auditors could perform reviews of JS - They could sign JS they find safe with their PGP keys and upload it to so…

You need to sign an entire chain of HTML+JS+CSS+everything else, as you can build keylogger with CSS. Web if weird. I wouldn't be surprised to find out that one can build keylogger with some tricky font file. But it definitely should be possible to build an addon like that. Although it would require some good cryptographers as not to make a mistakes.

I don't think there are any browser standards for that. I guess that such a webapp is too niche and this threat is extremely niche, so very few people would care for it to be a general purpose standard.

Re: End-to-end encryption in the browser

#88
post #56
post #46

Earlier quoted context omitted.

It's using end-to-end encryption to address a slightly different threat model than the usual one: the website operator doesn't want the liability/danger of holding cleartext data. E2E does solve this even in the browser scenario. Now an attacker who dumps the server's disks doesn't compromise user data, they'd have to activate modify the website. This raises the bar of a successful targeted attack and aldosterone bas…

> It's true that this doesn't let you avoid trusting the provider, but you're not going to get that anyway - and this scheme is certainly no worse. (Arguably you're not going to get that on native apps either these days, thanks to closed-source app stores and automatic updates, and automatic updates are a very good thing.) There is no guarantee, but security researchers often check the contents of apps like WhatsApp,…

AFAIK Google Play serves apk signed by a developer. So it can't just serve another apk without possessing developer private key. So this attack is possible but would require coordinating few parties. On the contrary, Apple AppStore signs the binary with its own key, so they can serve whatever they want to whoever they want and nobody will notice.

Re: End-to-end encryption in the browser

#89

const encrypted = await window.crypto.subtle.encrypt( { name: "AES-GCM", iv: new Uint8Array(12) /* don't reuse key! */ }, key, new TextEncoder().encode(JSON.stringify(content)) ); This looks wrong. The iv should be a randomly generated string that is only used once. I'm not super familiar with modern Javascript, but I think you're just initializing a bunch of null bytes. Honestly, I feel like whoever designed AES int…

Well on the site it was said "We encrypt the content with that random key. In this case, we only encrypt the content once with the random key so we don’t need an iv and can leave it filled with 0 (I hope…)." Anyone think that is a good idea?

If the key is securely random AND only used once, it won't compromise the encryption. But it's a bad idea, since it requires enforcing that the key is a nonce, instead of just a key. It's a bad habit, and can easily lead to compromise (when someone inevitably uses it as example code in a situation where those guarantees don't hold, for instance.)

Re: End-to-end encryption in the browser

#90
post #17

I appreciate the effort, but this is one of those cases in which there isn't much security added by encryption. If I assume the website owner is malicious (or subverted by powers that be), I cannot trust the JS code provided by the website. Key disclosure is as trivial as one line hidden somewhere in megabytes of JS code delievered from the server. Which makes "end-to-end" part nearly meaningless.

So just load the JS locally from a browser extension. I know MEGA (end-to-end encrypted cloud storage) has an extension for that. I'm sure other end-to-end encrypted web apps (ProtonMail, Bitwarden, etc) could do the same.

https://mega.nz/extensions

Post reply on HN