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
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, ‘*’)
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 -
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
Remediation
Validate source of message -
1window.addEventListener(‘message’ event => {
2if(event.origin !== ‘http://login.sitea.com’) return
3setCurrentUser(event.data.name)
4})