DOM XSS using web messages

Description

This lab demonstrates a simple web message vulnerability. To solve this lab, use the exploit server to post a message to the target site that causes the print() function to be called.

Approach

After accessing the lab, I noticed no visible functionality, so I opened the developer tools to inspect the home page's code. A script tag caught my attention:

<!-- Ads to be inserted here -->
<div id='ads'>
</div>
<script>
	window.addEventListener('message', function(e) {
		document.getElementById('ads').innerHTML = e.data;
	})
</script>

This script has an event listener that listens for web messages and directly inserts the received message into a div with the id ads without proper sanitization. This meant that if I could pass JavaScript in a web message, I could achieve XSS.

I decided to host a malicious page on the exploit server that would contain an iframe of the vulnerable website with an event handler. This handler would throw a web message containing my payload to the home page, triggering the XSS.

Here is the code for my exploit web page:

<iframe src="https://0a5f0099038ea08097519121009a0048.web-security-academy.net" onload="this.contentWindow.postMessage('<img src=1 onerror=print()>','*')" style="height: 700px; width: 1000px">

The postMessage() function is responsible for sending the web message, which in this case is my XSS payload. The * specifies the target origin as a wildcard.

By embedding this HTML code in the body part on the exploit server and clicking "Deliver exploit to victim," the lab is solved.