One idea I had to solve the fundamental insecurity of web-based crypto was to add subresource integrity support to service workers.
Service workers are persistent and are essentially a piece of JavaScript which can intermediate all HTTP requests to an origin, which means a trusted service worker could verify the integrity of all loaded resources according to an arbitrary policy. Then you only need to secure the service worker itself. If you could specify the known hash of a service worker JS file, you could know that all future resource loads from the origin would be intermediated by that JS. Presumably, the service worker JS would change rarely and be publically auditable. (If the inconvenience of not being able to change its hash is too inconvenient, it could chainload a signed service worker file; you can implement arbitrary policies.)
This creates a TOFU environment. One logical extension if this were implemented would be to create a browser extension which preseeds such service workers with their known hashes, similarly to HTTPS Everywhere.
I am one of the editors of the SRI spec but I am currently on a month long vacation in remote places that doesn’t allow internet access (except this comment, written on a potato.)
signed pages is not able to prevent the loading of the website even if the signature is invalid
They should be able to implement this functionality for Firefox. They’re already using a blocking request filter, they definitely can prevent the page from being rendered if the check fails.
the keys in localStorage
Hm, why not just encrypt them with a key derived from the password? Or is there “remember password” functionality for convenience?
the idea is when you’re logged in, your keys stay in localStorage, and if you reload the html file (and if it is possible that it could have been tampered with) you are logged out and have to enter your password again. Password auto-fill can leak your password to an adversary too so you need to disable that, which is a big inconvenience.
Yes, this and also a soft reload (clicking a link or entering cryptpad.fr in the location bar) will hit the cache, only F5 flushes the cache. Something I forgot to mention in the blog is that verifying the cross-domain iframe html is kind of a pain since iframes don’t (yet) allow an integrity field. My solution was to load it manually first with fetch() api (which supports integrity) and then load it with the iframe afterwords and hope for a cache hit.
One idea I had to solve the fundamental insecurity of web-based crypto was to add subresource integrity support to service workers.
Service workers are persistent and are essentially a piece of JavaScript which can intermediate all HTTP requests to an origin, which means a trusted service worker could verify the integrity of all loaded resources according to an arbitrary policy. Then you only need to secure the service worker itself. If you could specify the known hash of a service worker JS file, you could know that all future resource loads from the origin would be intermediated by that JS. Presumably, the service worker JS would change rarely and be publically auditable. (If the inconvenience of not being able to change its hash is too inconvenient, it could chainload a signed service worker file; you can implement arbitrary policies.)
This creates a TOFU environment. One logical extension if this were implemented would be to create a browser extension which preseeds such service workers with their known hashes, similarly to HTTPS Everywhere.
I created an issue suggesting this at the Subresource Integrity WG: https://github.com/w3c/webappsec-subresource-integrity/issues/66
I am one of the editors of the SRI spec but I am currently on a month long vacation in remote places that doesn’t allow internet access (except this comment, written on a potato.)
Having said that, you’ll likely be interested in this web hacking challenge of mine from last year. It involves SRI and Service Workers: https://serviceworker.on.web.security.plumbing/
I’ve summarized my findings here: https://frederik-braun.com/sw-sri-challenge.html
Reminds me of the format we wanted to use in Firefox OS next, which never came to be.
There’s also an IETF draft following a similar goal: https://datatracker.ietf.org/doc/html/draft-yasskin-webpackage-use-cases-01
I’ve been thinking about this too. Nice to know that the signed pages webextension already exists!
They should be able to implement this functionality for Firefox. They’re already using a blocking request filter, they definitely can prevent the page from being rendered if the check fails.
Hm, why not just encrypt them with a key derived from the password? Or is there “remember password” functionality for convenience?
the idea is when you’re logged in, your keys stay in localStorage, and if you reload the html file (and if it is possible that it could have been tampered with) you are logged out and have to enter your password again. Password auto-fill can leak your password to an adversary too so you need to disable that, which is a big inconvenience.
What’s the point of using localStorage if you are logged out when you reload? Sharing the logged-in state across multiple browser tabs?
Yes, this and also a soft reload (clicking a link or entering cryptpad.fr in the location bar) will hit the cache, only F5 flushes the cache. Something I forgot to mention in the blog is that verifying the cross-domain iframe html is kind of a pain since iframes don’t (yet) allow an integrity field. My solution was to load it manually first with fetch() api (which supports integrity) and then load it with the iframe afterwords and hope for a cache hit.