PROFESSIONALCOMMUNITY

Postmessage

  • Last updated: September 9, 2021

  • Read time: 7 Minutes

DOM Invader's Postmessage tab also drastically simplifies testing for DOM XSS vulnerabilities using web messages. It lets you intercept messages that are sent on the target website, view useful details about them, as well as edit and resend them to probe for vulnerabilities. In some ways, this is a web message equivalent of Burp Proxy's HTTP history and Burp Repeater.

You can also allow DOM Invader to automatically generate additional messages to try to identify vulnerabilities on your behalf.

If you need to brush up on web message vulnerabilities, we've covered this topic on our Web Security Academy, where you can also find some deliberately vulnerable labs to practice on.

Enabling web message interception

By default, web message interception is switched off. To enable it, click the Burp Suite icon in the upper-right corner of the browser, go to the DOM Invader tab, then toggle the Postmessage interception is on/off switch.

Enabling web message interception in DOM Invader

When prompted, click the Reload button to apply the changes. The Postmessage tab should now be available in the DevTools panel.

Postmessage settings

From the DOM Invader settings menu, there are also several settings that let you tweak DOM Invader's behavior when working with web messages:

Viewing intercepted messages

Once you've enabled web message interception, the Postmessage tab will automatically list all web messages that are sent on the page.

Viewing intercepted messages in DOM Invader

Which messages you see depends on your settings:

  • If you enable web message interception, but none of the other web message settings, DOM Invader will intercept any messages that are sent and forward them unchanged.
  • If canary injection is enabled, DOM Invader will send each message for a second time, with the canary injected in the data, and a third time, with both the canary a series of test characters that may be useful for constructing an exploit if they appear unencoded or unescaped in a sink.

The following information is displayed about each message:

  • ID: A unique ID for the message. Note that if you enable DOM Invader to generate its own web messages, these will not have an ID.
  • Severity: An estimation of how dangerous the identified vulnerability is. The mere presence of a web message is always an "informational" vulnerability, but if you enable some of the extra web message options, DOM Invader will flag messages where it successfully passed data into a sink, for example.
  • Confidence: An indication of how confident DOM Invader is that this vulnerability is present. Lower-confidence vulnerabilities will generally require manual confirmation.
  • Type: The type of the web message. This could be string, json-string, or json-object.
  • Origin: The origin of the web message, that is, the URL scheme, domain, and port of the page from which the message was sent.
  • Data: The actual content of the message.
  • Stack Trace: Clicking this link outputs the stack trace to the console. You can use this to easily find the exact line where the message event listener occurs.

Viewing message details

You can click on a message to view more detailed information about it and resend the message with different values to probe for vulnerabilities. If you have enabled any of the additional postmessage settings, you can also toggle whether you want to see the original data or the data from the modified message.

Viewing web message details in DOM Invader

DOM Invader automatically detects whether the origin, data, or source properties of the message are actually read by the JavaScript on the page. This can provide clues as to how exploitable the message may be.

Origin accessed

If the origin of the message is never accessed, this is an indication that it is not being validated at all. As a result, you may be able to send a message from an arbitrary origin.

Even if the origin is accessed, that doesn't necessarily mean that the site is secure. First of all, just because it's being accessed doesn't mean it's being validated. Even if it is, by digging deeper into the source code via the provided stack trace, you may be able to work out a way to bypass this validation. For some ideas on how to do this, check out the Web Security Academy.

Similarly, some websites may validate the origin once, but you may be able to find other functions that fail to do this.

Data accessed

As the data of the message is where you'll inject any potential payloads, if the site never reads the data in the first place, it's clearly not going to be passed to a sink. Therefore, the message is of no interest.

Source accessed

The source property of a web message is a reference to the window from which it was sent. In practice, this will usually be a reference to an iframe. Websites often validate the source property as this is a more robust way of ensuring that the message came from a specific, trusted iframe.

As with the origin, keep in mind that even if the source is being read, this doesn't necessarily mean that it's being validated properly or that this validation can't be bypassed.

Spoofing the message origin

From the DOM Invader settings, you can select the Postmessage origin spoofing option. When enabled, DOM Invader will automatically replace the origin of any intercepted message with a fake origin in the following format:

target-site.com.faketarget-site.com

For example, if you were testing on portswigger.net, the spoofed origin would read:

https://portswigger.net.fakeportswigger.net

Spoofing the origin enables DOM Invader to identify event listeners that use flawed logic or regular expressions to validate the origin of messages. For example, this fake origin would easily bypass any validation that checks whether the string starts or ends with a trusted domain name.

If you do not enable this option globally, you can enable it for specific messages by selecting the Spoof origin checkbox:

Spoofing the origin for a specific web message using DOM Invader

Note

This checkbox is hidden whenever origin spoofing is already enabled globally.

Injecting a canary via web messages

From the DOM Invader settings, you can select the Canary injection into intercepted messages option. When enabled, DOM Invader will inject the canary string into the data of any intercepted messages. The canary is highlighted in the list of messages.

If you click on a message, you can use the Show drop-down to toggle between the original data and the modified data containing the injected canary so that you can compare them.

The Postmessage tab also provides that same search functionality as the augmented DOM to help you filter the list based on a particular string.

Automatically generating new messages

From the DOM Invader settings, you can select the Generate automated messages option. When enabled, DOM Invader identifies event listeners on the page and sends its own web messages to trigger them. This is useful in cases where you want to test a potentially vulnerable event listener but either:

  • No web messages are being sent on the page at all.
  • Web messages are being sent, but none of them are triggering the particular listener that you want to test.

DOM Invader attempts to infer information about the structure of the data that each event listener is expecting, and uses this to try to send suitable messages. Based on how these are handled, it then generates more messages, with the data adjusted accordingly. This enables DOM Invader to tailor its messages in order to successfully hit additional code paths that potentially lead to more dangerous sinks.

For example, consider a message handler that expects to receive a URL, and follows different code paths depending on whether this contains the string http:, https:, or neither. This might look something like this:

window.addEventListener('message', function(e) {
  var url = e.data;
  switch (true){
    case (url.indexOf("http:") > -1):
      // Do something
      break;
    case (url.indexOf("https:") > -1):
      // Do something else
      break;
    default:
      // Invalid URL: Must contain string "http:" or "https:"
      break;
  }
}, false);

In this case, DOM Invader may send an initial message containing a blank string, but follow it up with two more messages, one containing http: and one containing https:, so that all three states are tested and the input flows into all three branches. These follow-up messages will also contain the same test characters that DOM Invader injects with the usual canary (<>"':) so you can check what's being escaped or encoded.

Note

The canary used in auto-generated web messages is always followed by a sequential number and a hyphen character.

You can always distinguish messages that were self-generated by DOM Invader because they are not assigned a numeric ID.

Replaying web messages

Once you identify a potentially vulnerable web message, DOM Invader also makes it easy to test different ways to exploit it. When you select a web message, you can modify its properties and click Send to replay the message using new values, just like you do with HTTP requests in Burp Repeater.

For example, you might identify a message where:

  • The event listener does not validate the origin.
  • The data is passed into a sink, such as element.innerHTML.
  • The characters <> and " are unescaped.

In this case, you can select the message, change the data to a typical XSS vector, such as <img src=1 onerror=alert(1)>, and click Send. If the alert() is called, you have successfully found DOM XSS using the web message source.

Generating a proof-of-concept for web message vulnerabilities

Once you successfully identify an exploitable vulnerability, DOM Invader lets you generate an HTML proof-of-concept at the click of a button.

To do this, simply select the vulnerable web message and modify the values as required for the exploit, then click Build PoC. The HTML is saved to your clipboard so you can easily include it in a bug report or solve some of our DOM XSS labs on the Web Security Academy by delivering it to the simulated victim via the provided exploit server.