Hijacking service workers via DOM Clobbering

We discussed this vulnerability during Episode 173 on 05 December 2022

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.