Using Service Workers to improve the security model of the web

# Daniel Huigens (2 days ago)

A short while back I wrote a blog post [1] on using Service Workers to mitigate the "Javascript Trust Problem" of client-side crypto [2], which is that the client trusts the server every time it opens a web app, and client-side crypto therefore can't protect from the server much. (Previously discussed at [3] and [4].) By installing a Service Worker, which sits between the client and server and verifies the integrity of all (updated) source code, we can improve that to Trust On First Use.

This allows us, for example, to make it impossible to compromise the Javascript of a web app for existing users when the server gets hacked, by requiring, in the Service Worker, that all code be signed with a given public key. This is necessary for a web app that client-side encrypts data and doesn't trust the server. (I can elaborate on threat and security model if you want, I wanted to keep a modicum of brevity.)

Now, some of you are probably yelling, "But Service Worker lifecycle!" Indeed, Service Workers have been carefully designed to update on every page load, and the old Service Worker can't prevent a compromised, new Service Worker to be installed, for a good reason. It's not necessary to change that. However, it would be nice to be able to read the code of the new Service Worker in the old Service Worker, in the updatefound event. Then, if that new code doesn't match the signature, we can show a big fat warning and the user can choose (for example) not to enter their password.

One option is to allow the old Service Worker to request the new Service Worker file from cache with fetch('/service-worker.js', {cache: 'only-if-cached'}). However, if the new Service Worker calls skipWaiting(), that request currently gets canceled. To solve that, we could make updatefound an ExtendableEvent. Furthermore, Firefox seems to have a separate cache for Service Worker files.

Another option is a dedicated property or function, like registration.installing.scriptBody or updatefoundevent.newSource. (Although it would still be nice to make updatefound an ExtendableEvent, to allow the Service Worker to fetch a public key from somewhere, for example.)

Let me know what you think!

Best wishes, Daniel Huigens

[1] blog.airbornos.com/post/2017/08/03/Transparent-Web-Apps-using-Service-Worker [2] tonyarcieri.com/whats-wrong-with-webcrypto#the-ugly-we39re-still-in-a-browser_1 [3] lists.w3.org/Archives/Public/public-web-security/2014Sep/0006.html [4] lists.w3.org/Archives/Public/public-webappsec/2017Apr/0042.html

Contact us to advertise here

Want more features?

Request early access to our private beta of readable email premium.