[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]]