This (rightfully) comes up every time some browser-based encryption tool is posted. It seems like the desire for such tools isn’t going to go away. Is anyone working on solutions for making distribution of JavaScript applications more secure?
There’s a range of assurances you could try to provide, e.x. signatures from the author (or even 3rd parties), prompting for updates, etc. It would likely require support from browsers.
At one point I investigated using service workers to intercept subsequent app updates to check signatures but there was no way to prevent the service worker itself from being replaced (probably because it would be easy for a site to permanently “brick” itself in users browssr).
> At one point I investigated using service workers to intercept subsequent app updates to check signatures but there was no way to prevent the service worker itself from being replaced (probably because it would be easy for a site to permanently “brick” itself in users browssr).
Cyph nailed this back with appcaches, later migrating to service workers (and ultimately got a patent for the solution), but the implementation of the solution itself got an entire protocol canned by one browser (HPKP).
This was "solved" by a online crypto tool (can't remember which) that basically did HPKP suicide every 30 minutes and had a service worker that loaded cached assets on failure. So the browser would pin to a key that was deleted within minutes and then all subsequent requests would only go through the service worker until the pin expired.
As far as I'm aware that means their approach no longer works (across browsers), and, though it was a fantastic idea, it did require you to trust that they really were throwing their keys away (a trust model slightly weaker than TOFU).
We (Cyph) have been pretty disappointed in the Chrome team's decision to kill HPKP.
Paraphrasing, but IIRC the reasoning pretty much boiled down to "it's a pain to maintain and Expect-CT is kind of similar anyway" — which I think is a really weak justification for harming end user security and breaking established APIs that people depend on in production. Fingers crossed that Firefox keeps it alive!
That said, it doesn't entirely break WebSign in Chrome, just weakens a bit further below strict TOFU. https://www.cyph.com/websign goes into detail, but WebSign has some client-side logic to validate its own hash against a signed whitelist. The major downsides to relying on this are:
1. It depends on a caching layer, not a security feature. This means that any guarantees are potentially out the window if a browser vendor decides to do something crazy for performance reasons or whatever.
2. It opens up an attack vector where it can be forcibly unpinned by filling up the user's disk and making the browser evict the cached WebSign instance.
All in all I think it's still basically fine, but shipping an optional browser extension for hardening WebSign is now a higher priority because of this.
There was a site posted on HN a while back that had an interesting take on a solution to this: they had a service-worker that checked github.com for the latest version of the app code and itself (along with the standard subresource integrity of course). That description doesn't do the system justice, as to my memory it seemed like a pretty sound system as long as your public repo remains uncompromised.
Unfortunately can't remember the name of the website nor exactly what it did...
A browser add-on that is manually installed (which I believe would stop any potential insecure/unintended automatic update) could check a digital signature embedded in a formatted comment inside the JS file. That is relatively easy to implement, but you will also want some sort of PKI for key distribution and revocation.
The idea came to my mind that people could create websites on domains of the form [some SHA hash].example.com and reference from the root HTML page a file with the name [the same SHA hash].js and this could trigger a special mode in the browser where it checked that the JavaScript file hashed to the given value, and then refused to load any other scripts.
The bootstrap JavaScript file could contain the code needed to download more files, and to download a digitally signed list of file hashes, which it could check against a hardcoded public key. Also the browser would have to remember a flag for that domain to require this same bootstrapping process every time, to stop downgrade attacks.
There’s a range of assurances you could try to provide, e.x. signatures from the author (or even 3rd parties), prompting for updates, etc. It would likely require support from browsers.
At one point I investigated using service workers to intercept subsequent app updates to check signatures but there was no way to prevent the service worker itself from being replaced (probably because it would be easy for a site to permanently “brick” itself in users browssr).