postMessage#
postMessage safely enables cross origin communication between objects, e.g., between a page, pop up, between a page and an iframe.
Requirement: You need to have some kind of reference to the other origin with whom you want to talk to. It can be an embedded iframe
Sender
targetWindow.postMessage("hello other document!", "*");Receiver
window.addEventListener("message",function(message){console.log(message.data)});Limitation#
Let's assume, store.sitea.com wants to retrieve a username, so it listens for messages from login.sitea.com
window.addEventListener(‘message’ event => {
setCurrentUser(event.data.name)
})
Store.sitea.com embeds an iframe to login.sitea.com which runs below code
const data = { username: ‘PankajMouriya’ }
window.parent.postMessage(data, ‘*’)Imagine what if attacker embeds login.sitea.com
Remediation#
You can specify the destination origin for which the message is intended to
Validate Destination of message -
const data = { username: ‘PankajMouriya’ }
window.parent.postMessage(data, ‘http://store.sitea.com’)But again, because store.sitea.com listens for messages from any source as it does not explicitly mentions which source, an attacker can embed store.sitea.com and send bogus messages to it
Remediation#
Validate source of message -
window.addEventListener(‘message’ event => {
if(event.origin !== ‘http://login.sitea.com’) return
setCurrentUser(event.data.name)
})