[I also [posted about this](https://lists.w3.org/Archives/Public/public-webapps/2017JulSep/0052.html) on the mailing list, but I didn't receive any replies and I feel that this is important. Sorry if it comes across as spam.]
It would be nice if it were possible to reliably make a request from the updatefound event. Currently, if the new Service Worker calls skipWaiting(), the old Service Worker gets killed and its request canceled in both Chrome and Firefox, with no way to avoid it, because updatefound is not an ExtendableEvent.
Why? I'm trying to use Service Workers to solve the quite old and fundamental problem that on the web, you can't make applications that don't trust the server (and e.g. use client-side encryption) because the server sends you the code every time you open it. Basically, with Service Workers, I'm serving the code from SW cache instead, and only updating it if it matches some public log (in my case GitHub), in effect achieving some form of Binary Transparency on the web.
But, of course, the SW can update at any time. So, to make it secure, we need to check the new SW against GitHub as well, in the updatefound event, and warn the user if it doesn't match. (Of course, we can't prevent the update, but we can at least try to convince the user to close the web app before it steals their private keys.)
This is totally the correct place to make this feature suggestion.
You're not the first to suggest features that make the SW somehow resistant to updates. The problem is, the same feature could be used by a malicious service worker to prevent removal.
At the moment, we guarantee that if the worst happens, and someone gets an evil service worker installed on your origin, you can undo the damage at the next update check. If the bad guy managed to set a long max-age on the script, it'll be capped to 24hrs.
Hi @jakearchibald, thanks for your response.
I'm not requesting the ability to prevent a Service Worker update, only the ability to delay it slightly. If the old Service Worker calls waitUntil with a promise that takes too long, say more than a few minutes or so, I'm perfectly fine if it gets killed and updated.
That last part is already allowed by the spec, I think: "However, the user agent may impose a time limit to this lifetime extension."
Basically, all I want to do in the updatefound event is make one or two network request and conditionally warn the user about the update.
Ahh, sorry for misunderstanding!
Btw https://github.com/w3c/ServiceWorker/issues/822 relates to preventing updates.
Also similar https://github.com/w3c/ServiceWorker/issues/761
Thanks, I hadn't seen those. The use case in https://github.com/w3c/ServiceWorker/issues/822#issuecomment-224193401 is basically the same as mine, namely, 1) a web app that handles potentially sensitive user data and doesn't send it to the server, or only does so after encryption, and 2) wants to verify that all updates to the web app are authenticated. Together, those things move the web app from "trust the server every time you open it" to trust-on-first-use.
The only thing that differs is what happens when an update is not authenticated:
One issue to consider is, what happens if there is no open/visible client of the Service Worker? That can happen if a third party origin loads the web app in an iframe (and either hides it, or the web app responds with X-Frame-Options: deny). It can also happen when the SW receives a push event, although that can be prevented ahead of time by.. not registering for push events. It might be an issue for, say, encrypted chat apps though.
One option if we go with option 2 above, is to request permission for Web Notifications ahead of time. Then, we can always warn the user in the updatefound event. However, it's probably unwise to rely on users to grant that permission for security warnings. Another option is to not update the Service Worker if the web app responds with X-Frame-Options: deny (related Chrome and Firefox bugs).
Similarly, with option 3 above, we could default to not updating if there is no open client.
I think I've found a workaround to this issue: instead of calling (the nonexistent) waitUntil in an updatefound event, call waitUntil from a preceding functional event (e.g. fetch).
I believe all Service Worker updates will be preceded relatively shortly by a functional event, be it a fetch event during the page load which triggered an update, or a functional event that itself triggered the update, although it's not guaranteed: "The user agent may call [the Soft Update algorithm] as often as it likes to check for updates." (Please correct me if I'm wrong and browsers actually do this.)
Another downside is that, AFAICT, you have to register for all known functional events, because if you don't and it fires, the Service Worker is updated but not started (https://w3c.github.io/ServiceWorker/#handle-functional-event-algorithm, step 4.2). That is of course impractical and bad for performance (since the SW is uselessly started and made to keep running with waitUntil() if an update isn't found), so it would still be nice to have waitUntil() on updatefound events. (And also because, as mentioned, this workaround is not guaranteed to be correct.)
This would be solved by this proposal: https://github.com/w3c/ServiceWorker/issues/822#issuecomment-403251848
Hi all,
I just wanted to say why I think some version of this proposal would have a _very_ positive impact on聽the future of the web:
Firstly, I agree with your reasoning behind preventing a Service Worker (SW) from blocking updates to itself _indefinitely_. 聽Unlike #822 and #761 , this proposal _does not_ suggest preventing SWs from being updated for a significant period of time (and certainly not indefinitely).
Many of us would _love_ to see the web become more trustworthy, at least for sites that choose to implement what @twiss is trying to enable. 聽By allowing web app creators to guarantee to users that they (the users) are not running a different, perhaps-malicious version of a web app than other users on the same site, and by being able to warn users when an unauthorized version of said web app's JavaScript is about to be executed, this greater trust can be achieved.
As a web developer, if I deploy a buggy SW, I want to be able to replace it quickly. 聽IIUC, the latest version of his proposal merely seeks to guarantee that a聽small window of time exists (e.g., 60 seconds) for the old SW to somehow warn the user that a possibly-malicious SW is about to replace it.
By providing this guarantee via the spec, you will enable a decades-long dream of web developers to come true -- for it to be possible to build web applications that are approximately _as trustworthy as native apps_, arguably more so, since web apps cannot run around on the user's hard drive to wreak havoc, but are instead trapped in the browser.
And for the majority of web apps who don't need such high security, they will remain unaffected.
Would love to see some version of this get accepted! :+1:
Most helpful comment
Hi all,
I just wanted to say why I think some version of this proposal would have a _very_ positive impact on聽the future of the web:
Firstly, I agree with your reasoning behind preventing a Service Worker (SW) from blocking updates to itself _indefinitely_. 聽Unlike #822 and #761 , this proposal _does not_ suggest preventing SWs from being updated for a significant period of time (and certainly not indefinitely).
Many of us would _love_ to see the web become more trustworthy, at least for sites that choose to implement what @twiss is trying to enable. 聽By allowing web app creators to guarantee to users that they (the users) are not running a different, perhaps-malicious version of a web app than other users on the same site, and by being able to warn users when an unauthorized version of said web app's JavaScript is about to be executed, this greater trust can be achieved.
As a web developer, if I deploy a buggy SW, I want to be able to replace it quickly. 聽IIUC, the latest version of his proposal merely seeks to guarantee that a聽small window of time exists (e.g., 60 seconds) for the old SW to somehow warn the user that a possibly-malicious SW is about to replace it.
By providing this guarantee via the spec, you will enable a decades-long dream of web developers to come true -- for it to be possible to build web applications that are approximately _as trustworthy as native apps_, arguably more so, since web apps cannot run around on the user's hard drive to wreak havoc, but are instead trapped in the browser.
And for the majority of web apps who don't need such high security, they will remain unaffected.
Would love to see some version of this get accepted! :+1: