[This lab](https://portswigger.net/web-security/dom-based/controlling-the-web-message-source/lab-dom-xss-using-web-messages) showcases a **DOM-based XSS** vulnerability caused by insecure use of the `postMessage` API and DOM sinks like `innerHTML`. --- ##### **Vulnerable Code Summary** The following JavaScript on the target site is responsible for the vulnerability: ![[CleanShot 2025-04-12 at 15.54.56.png]] ```javascript window.addEventListener('message', function(e) { document.getElementById('ads').innerHTML = e.data; }); ``` - This code listens for **web messages** sent using `postMessage()`. - It **blindly trusts** the message content (`e.data`) and **injects it into the DOM** using `innerHTML`. - No validation or sanitization of the origin (`e.origin`) or message content is performed. - This creates a classic DOM XSS scenario. --- ##### **How the Exploit Works** We use the **exploit server** to craft and serve a payload that: 1. Embeds the target site inside an iframe. 2. Once the iframe loads, sends a crafted message (`postMessage()`) to the iframe's content. 3. That message contains HTML/JS that is inserted directly into the target DOM (`innerHTML`). 4. The malicious HTML triggers a JavaScript execution (via `onerror` event handler). 5. The attack calls the built-in `print()` function as proof of execution. --- ##### **Exploit Payload Explained** ```html <iframe src="https://YOUR-LAB-ID.web-security-academy.net/" onload="this.contentWindow.postMessage('<img src=1 onerror=print()>','*')"> </iframe> ``` **Element Breakdown:** - `<iframe>` embeds the target site. - `onload="..."` ensures the code only executes once the iframe is fully loaded. - `this.contentWindow.postMessage(...)` sends a message to the iframe's content. **Injected Message (XSS Payload):** ```html <img src=1 onerror=print()> ``` - The image source is invalid (`src=1`), causing a **loading error**. - The `onerror` attribute triggers the execution of the JavaScript: `print()`. - This gets injected into the DOM via `innerHTML` by the target site’s `message` handler. --- ![[CleanShot 2025-04-12 at 16.02.06.png]]