Hijacking service workers via DOM Clobbering
The core vulnerability here is a case where a DOM clobbering attack could be used to hijack a service worker.
The flow is a complicated, you start off with your web-app loading, on that page is an element, something like:
<div id="cdnDomain" style="display:none">example.com</div>
Also on the page is some javascript (my own examples, not directly from the post)
let cdn = document.getElementById("cdnDomain").innerText
navigator.serviceWorker.register("/sw.js?host=" + cdn)
And then finally in the service work itself would import scripts based off the host
param. So if one could control the cdnDomain
value they could control where the server worker loaded the core of its code from.
The most interesting part of the post comes in a couple discoveries regarding quirks of getElementById
. I’m not sure if these are entirely novel, but often with DOM clobbering attacks you want your DOM element that is doing the clobbering to exist earlier in the DOM than the one being clobbered. this is not always the case though, the author calls out a couple tags that will take precedence even if they occur later in the page: <html>
and <body>
tags. Even if it doesn’t quite make sense for those tags to be present, if injected it seems they will clobber other elements with the same ID. This includes if they are present inside of an <svg>
element.