Solution to the ‘Browser Crypto Chicken-and-Egg Problem’?

First of all, as I mentioned in a comment under the question, this method will not work if the user has any browser extension running that modifies the page source since the signature would no longer remain valid. This also applies to antiviruses that intercept and inject scripts into web pages. Browser extensions can easily be disabled but disabling the antivirus may not be possible in some cases.

Secondly, although this procedure can work when using a laptop/desktop, making it work on smart phones will be much more cumbersome, perhaps almost impossible. As far as I know, there is no easy way to save web pages as html in browsers on iOS.

Finally, to answer the question asked, there does seem to be a way for the server to load a malicious version of the page. The HTTP Refresh header, which is an unofficial header, but appears to be supported by many browsers, could potentially allow the server the to redirect the user to a malicious page. By serving the original page and setting a refresh time of, say 5 minutes, the server could be reasonably sure the refresh occurs after the user has verified the integrity of the page, and then hope the user does not notice the redirect. Since this is sent as a header, it will not affect the integrity of the original page and the signature will remain valid.


It is possible to do this via browser extensions and it is not necessary for the user to download the signed web application and run in locally.

Since you already have a trusted reviewer/trusted third party that does a code review and signs the web app along with all (transitive) sub resources. They can also publish a browser extension that does the verification on the fly. The hashes that are checked against might be built in to the extension or downloaded regularly from a server of the TTP.

There are a lot of hooks that are provided to such browser extensions to control the executions of requests. The trouble is that browsers start to execute code as soon as it is there while a request is not yet complete. That means that the web app must be written in such a way that the execution starts after the request is received and validated. The validation can be done through this (if it were implemented anywhere; haven't tested it) or by reading the page content after the onCompleted callback.

The trouble is that this might be insufficient. If the web app is misbehaving it might not wait until the request is fully loaded and start sending data off to somewhere else. A CSP policy enforced through the extension might be the way to go there. Additionally, the extension might block (through the webrequest API) any network requests from the web app until it is verified. If the verification failed, the extension can close the tab and open a notification saying that the web app source changed in an unexpected way which might mean that the operators tried to sneak something in or simply that some other extension manipulated the source.

Sadly, it doesn't seem to be possible to look at the actual received response through the extension API which means that the web app might be sneaky by running some JavaScript and immediately removing the evidence that some JavaScript was executed. I'm not sure there is a way to disable JavaScript for a short amount of time as long as the page is not validated.

In case this is solvable, then you've added three more trusted third parties, because you now trust Google, Apple and Mozilla as the operators of their respective Web Extension stores.

If it works this has great user experience because new versions of the web app can be reviewed by the TR and the respective hashes added to the extension to be verified.


I read this about signal pretending they can use SGX so A can remotely assert that B run a trusted code : https://signal.org/blog/secure-value-recovery/

I don't knwo if they found new theoretical concept or if this is just a stack of protection with the hope that they don't all fall off. The technical details are not trivial.

Do you think it could be a solution ?