Hacker News new | ask | show | jobs
by AgentME 3476 days ago
> At the end of the day, window.crypto can be absolutely anything. ... If you must run the signal protocol in-browser, run it in Electron, or as a Chrome app ... At the end of the day, window.crypto can be absolutely anything. If we can bundle all primitives with the rest of the application code, we can verify the integrity of that one JS bundle

If the attacker is running code within the same javascript context, within the browser's process, or within the user's operating system kernel... then you're hosed. Anything can be anything. Other javascript within the same context could redefine global functions, intercept objects passed through them, and mutate function references in your JS bundle. Or it could just log the DOM! A browser plugin or a kernel rootkit can keylog the user. The only defense an application has against the user's own machine being compromised is obfuscation, and that's a losing battle.

There are real issues with doing cryptography with users' keys in web pages, but it's not "their machine might be compromised" (and Electron doesn't solve that anyway). Even if the page javascript correctly stores user keys in localStorage where the server can't see them, nothing stops the server from serving you some backdoored javascript tomorrow which silently uploads your localStorage to the server. This might be correctly solvable with ServiceWorkers, though you'd want users to have some way to verify that they have the correct and peer-reviewed ServiceWorker source running. The easiest way to do that would be some kind of local application or browser plugin, but then at that point that you've involved a local application you've missed some of the original goal at keeping it all in a browser, and it would probably be easier for everyone involved if the crypto just happened in the local application to begin with.

Interestingly, some `window.crypto` functions actually solve some of the problems with running cryptography in web pages. You can create and use a crypto key that is handled by the browser and never has its key material exposed to javascript. Even if an attacker injects javascript into the page or the server serves malicious javascript the next day, there's no way to steal the key material. `window.crypto` can effectively provide a virtual HSM from the web page's perspective.

2 comments

I've recently done some research in this direction and was kind of startled that there appears to be practically no interest in how to secure (for example "cryptomessenger"ish) SPAs. There are some things that can be done to compartementalize things a bit (eg. web workers), in the hope that it might mitigate next days' browser bugs, but at the end of the day everyone seems to put a huge amount of trust into a runtime environment of startling and ever increasing complexity and thus a security track record that's mediocre across all vendors at best.

Further adding to it are untethered, unchecked extensions in eg. Firefox. Every extension in Firefox is essentially running with full "browser root" privileges. Chrome at least has a privilege system that tries to avoid allowing every extension to attach a debugger to anything.

(I was also surprised that "how do i run that untrusted JS in my JS context 'safely'?" is a question asked and answered many times)

Two notes:

2) There is interest and progress on securing web applications: - For early research papers look into 'Privilege Separation in HTML5 Applications' by Devdatta Akhawe et al. <https://www.usenix.org/system/files/conference/usenixsecurit.... - For more practical concerns, see the stuff coming out of the W3C WebAppSec Working Group (CSP, Suborigins, etc.). - For Sandboxing/Compartmentalization of code, see the Realms proposal coming in to a future version of ECMAScript (JavaScript): <https://github.com/caridy/proposal-realms>

2) Firefox new-style extensions (WebExtensions) are in fact least-privilege.

HSM? What do you mean? What does it stand for? Heisenberg state machine?

How can the window.crypto API create and use a crypto key that's handled by the browser?

>HSM

Hardware Security Module. It's a piece of hardware that goes in a server and manages encryption keys for the server without ever exposing the keys to the server. Usually they're made so that it's infeasible to extract the keys even with access to the hardware: they're made hard to open, covered in epoxy, they erase their keys if the case is breached, etc.

>How can the window.crypto API create and use a crypto key that's handled by the browser?

There's a function for creating a key and you get an opaque object back out. You can pass the key to encrypt and decrypt functions. You can save the key object into IndexedDb, but you're still just dealing with an opaque object reference. There is an export key function, but it only works if the key was created with the "extractable" flag turned on.

The function is `window.crypto.subtle.generateKey`JavaScript can't access the generated key unless you export it using `window.crypto.subtle.exportKey`.

If anyone is interested in the WebCrypto API I recommend this talk by Charles Engelke: https://www.youtube.com/watch?v=D2kEViWKUh0

Hardware Security Module.

> How can the window.crypto API create and use a crypto key that's handled by the browser?

By setting extractable to false when creating the key, see https://www.w3.org/TR/WebCryptoAPI/#dfn-CryptoKey-extractabl...