Live data from Hacker News

End-to-end encryption in the browser

blog.excalidraw.com

61–70 of 112 posts

Re: End-to-end encryption in the browser

#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 some server

- Users could choose to trust certain auditors

- Every time you visit a site that you choose to require this kind of validation, you could check that the hashed JS matches the key

I guess we’re going the way of PKI+SHA hashes of distributed binaries all over again though. Also, if the website updates JS, you’d need to wait for auditors to review it, and there’s a whole mess there (websites would probably have to serve beta versions of their code ahead of release so auditors could have time to review them). Finally, JS would have to be static across all users and I’m not sure how feasible this is.

There is some benefit, though? Now you are distributing the trust over ProtonMail and your trusted auditors. This could be useful if we find ProtonMail to be compromised one day. This might even spawn businesses aimed solely at reviewing websites’ code.

There has to be a better way to do this. How can we bring ‘code review’ to web applications?

Re: End-to-end encryption in the browser

#63
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.

I'm not refuting your point here but it feels like on HN everytime we hit any web topic there are the kind of comments about "wait but this could happen / what if the website owner is malicious / included some wonky code he doesn't know about, etc".

They're not wrong, but also not the point of the article.

>As the maintainer of Excalidraw, I now sleep much better at night. If the hosting service gets compromised, it doesn’t really matter as none of the content can be decrypted without the key.

This seems to be the point of the article, and valid IMO. Yet on HN more and more we get dragged off on these larger state of the web topics. They're not wrong either, but I feel like the volume sort of drown out the point / valid topics too.

Re: End-to-end encryption in the browser

#64

    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 intended for people to make this mistake, because half of the sample code I see has this error, and it would have been easily avoided by specifying the IV length in the standard and requiring libraries to automatically generate it and prepend it to the ciphertext rather than letting callers have control over how it is initialized and stored.

Re: End-to-end encryption in the browser

#65
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.

You can certainly do it, but the rest of the users will stay vulnerable.

Re: End-to-end encryption in the browser

#66
post #21
post #19

Earlier quoted context omitted.

It's open source :)

And how can I be sure that the code delivered by the server is the same code as in the public codebase? Nothing stops the owner of the service to run arbitrary JavaScript in Users' browser.

Don't this still apply to a native client? You can be sure unless you build the client from source, but you can also build the website from source too right?

Re: End-to-end encryption in the browser

#67

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…

Yeah, the WebCrypto API has a built-in function for this. I hope the author fixes the code, because this is otherwise a dangerous tutorial.

window.crypto.getRandomValues(new Uint8Array(12));

If the author followed the MDN guides for it, they would have noticed that the example code also uses a random array. https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypt...

Re: End-to-end encryption in the browser

#68

Earlier quoted context omitted.

well, not the whole url, obviously, otherwise the router wouldn't know where to send the request

The entire URL is encrypted, the router doesn't need to know anything about the URL to route the packets. The only thing that can leak when you make an HTTPS connection is the DNS query.

The SNI leaks without ESNI:

https://en.wikipedia.org/wiki/Server_Name_Indication#Securit...

Re: End-to-end encryption in the browser

#69
post #11

Earlier quoted context omitted.

Urls are encrypted.

well, not the whole url, obviously, otherwise the router wouldn't know where to send the request

You are confusing layer 4 and later 7 concepts.

Spend some time with wireshark running while you visit “google.com” in a web browser and you’ll get a better intuition on the topic.

Re: End-to-end encryption in the browser

#70
post #21

Earlier quoted context omitted.

And how can I be sure that the code delivered by the server is the same code as in the public codebase? Nothing stops the owner of the service to run arbitrary JavaScript in Users' browser.

If the JavaScript bundle that is being served is built on a public CI/CD service, it could be possible to do the following, for transparency and verification: - Include in a header comment: the build URL, Git SHA-1 of the commit, and other metadata - Sign the bundle using public/secret key cryptography Having the build URL and sources URL help with discoverability and transparency, while integrity can be verified wit…

Yes, but there's no provision in the browser to do these kinds of integrity checks. If the browser isn't verifying it there's no point in adding any of this info, because it can be substituted covertly. In principle such 'version-pinning' could be added to the browser, but no-one has done so yet.
Post reply on HN