postMessage API Implementation and limitations
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
![](../../../images/sop/postmessage1.png)
Sender
1targetWindow.postMessage("hello other document!", "*");
Receiver
1window.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
1window.addEventListener(‘message’ event => {
2setCurrentUser(event.data.name)
3})
4
Store.sitea.com
embeds an iframe to login.sitea.com
which runs below code
1const data = { username: ‘PankajMouriya’ }
2window.parent.postMessage(data, ‘*’)
![](../../../images/sop/postmessage2.png)
Imagine what if attacker embeds login.sitea.com
![](../../../images/sop/postmessage3.png)
Remediation
You can specify the destination origin for which the message is intended to
Validate Destination of message -
1const data = { username: ‘PankajMouriya’ }
2window.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
![](../../../images/sop/postmessage5.png)
Remediation
Validate source of message -
1window.addEventListener(‘message’ event => {
2if(event.origin !== ‘http://login.sitea.com’) return
3setCurrentUser(event.data.name)
4})