3

While trying to understand the recent controversy involving ProtonMail, I started to wonder if its possible to verify that the opensource JavaScript being sent from the server to the client hasn't been tampered with.

If I understand correctly, you cannot use E2EE in the browser because technically if the server was compromised the server could send malicious JavaScipt to the client and respond with the client's secret encryption key/password.

If I am a developer, how could I ensure that my client is receiving the same JavaScript that is stored in my public GitHub repo? Is this even possible?

  • 2
    The easiest would be to not store the JavaScript on the server at all. Have users install the greasemonkey extension then they can load the JavaScript directly from the GitHub themselves. – Daisetsu Jan 17 at 21:38
  • @Daisetsu interesting. Would you know if it is possible to have the JavaScript programmatically come from the GitHub repo directly without having to install an extension? – orangeMint Jan 18 at 21:15
  • No, the entire point is to NOT do it automatically. Allow the user to inspect exactly what they are executing, and not be vulnerable to a coerced or hacked github repo. – Daisetsu Jan 18 at 21:16
2

Generally speaking, I think what you are asking is impossible, or rather, it's unfeasible and probably not useful. The reason why it's unfeasible is that you would have to check that the code is the same as the official code (for example on GitHub), and you would have to do this every time you reload the page. The reason why it's probably not useful is that to be sure that a web page actually behaves correctly, you would have to audit all its code, every time. Even if the page really loaded the official code for a specific library, how do you know if the page then actually uses that code as expected? It might load the code but not execute it, or it could redefine some functions before using them, etc. And even if you audited all the code and you were sure everything is working fine, the next time you reload the page all this could have been changed.

When you download software from GitHub, you are ultimately trusting the provider of that code, that is, GitHub. When you install software from a Linux repository, you are trusting the repository servers. And when you execute software on a web page (javascript), you are basically trusting the domain owner.

1

You can employ Subresource Integrity (SRI):

Subresource Integrity (SRI) is a security feature that enables browsers to verify that resources they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched resource must match.

You could use something like this:

<script src="https://example.com/example-framework.js"
        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
        crossorigin="anonymous"></script>

Any attacker modifying your external resource would have to modify your site too. Having the static HTML on a server and the Javascript on another creates two points for the attacker to change the scripts. But if the attacker compromises the HTML server, you lose.

  • I believe the threat model here is that the server OP is connecting to is untrusted. By "tampered with" they mean "different from what is in a public git repo". – AndrolGenhald Jan 17 at 21:48
  • @AndrolGenhald that is correct. – orangeMint Jan 18 at 21:17
  • 2
    @orangeMint In that case SRI isn't going to do anything for you. If you visit example.com, and it has you load some javascript from cdn.com, SRI allows example.com to tell the browser what to expect, so cdn.com can't modify it. If example.com is malicious SRI doesn't help. – AndrolGenhald Jan 18 at 21:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.