Secure Delivery of JavaScript
By Daniel Huigens on Saturday, April 25 2015
Airborn OS is an in-browser OS that encrypts your files in the browser.
Let's say you wanted, like us, to create a web application that encrypts your user's data with their password before it stores it on your servers. You value your user's privacy, after all. Does this buy you anything, though? Not really. Tomorrow you could change your code to send you your user's password. Even worse, you could do so for a particular user you're interested in. In other words, there's no way to securely deliver a web app without trusting the server.
Yet. What we need, in essence, is an external source that tells us what the HTML, CSS and JavaScript of the web app should be. People should be able to be notified when the source changes, in case you changed it to send you their password, and it should be the same for everybody, so that when one person checks the source, everybody can be more confident in it. A browser addon, or eventually the browser itself, could then check the server's responses with that external source.
One possibility for the external source is the browser addon itself. However, updates to Firefox addons can take a few weeks to be approved, which is simply too long when you need to change your JavaScript (more about that later). Browser updates also take six weeks, if we ever wanted to build this functionality into the browser.
A more promising possibility is the website's certificate. With the upcoming Certificate Transparency (CT), people will be able to keep track of certificates and be confident that everyone gets the same certificate. We could use a certificate extension to store the information we need. Currently, though, no Certificate Authority (CA) that I'm aware of actually allows you to put arbitrary information in certificates. One CA we asked worried about CA/Browser Forum requirements. One CA was willing to do it, but at a large sum per generated certificate, which is a disincentive you shouldn't want.
Finally, we could do something in between those two possibilities: store the information in the addon, but allow updating the web app by regenerating a certificate (which is faster). In other words, pin the information to the certificate. This is what we currently do for airbornos.com. We call it "HTTPS Content Signatures" (HCS) and the addon is here (code).
Once Certificate Transparency becomes a requirement in browsers[1], this means it's no longer possible to serve unknown certificates with a website (that's what CT is). That means it's no longer possible to serve unknown HTML or JavaScript to the browser as long as every known certificate is listed in the addon (that's what the addon does). Secure delivery of JavaScript, coming soon!
As promised above, one more note about updating the web app. Having to regenerate your certificate every time you update your web app is still quite unfortunate, especially if it means users of the addon are no longer protected. It might be necessary to reduce the amount of code that is protected this way. I'll offer two possibilities.
For the homepage and login page, you could separate form from function with a sandboxed iframe. However, there are many small problems with this to which I have no solution yet: it complicates scrolling, if you allow navigating the top frame (for links) that could be abused, and some things can't be moved to an iframe (e.g. <meta> tags).
For the web app itself, you could protect only a small "loader" and do in it whatever you want. What we do is decrypt the rest of the code with the user's password.
This is all by no means an easy or ready-made solution, but for web apps that are very serious about security, it could be an important building block.
Notes
[1] Since we have an addon anyway, we could build this requirement into the addon. We haven't done so yet, though.