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})