DOM-Based

DOM-Based XSS occrus when the vulnerability is caused by unsafe manipulation of the DOM in the browser; it executes entirely on the client-side with no interaction from the server after the initial page load.

Basic

The example below is based on TCM's Practical Bug Bounty course.

When an item is added to the below to-do application, no network traffic is generated (Figure 1).

Figure 1: Inspecting the network traffic of the application.

If we try a common JavaScript payload, we get a prompt box back (Figure 2).

// the JavaScript payload used
<img src="x" onerror="prompt()">
Figure 2: Executing a DOM-based XSS attack.

We can also use the above attack to redirect the user to another location (Figure 3).

// the XSS payload used
<img src="x" onerror="window.location.href='https://x7331.gitbook.io/boxes'">
Figure 3: Executing a DOM-based XSS attack with redirection.

DOM Invader

The example below is based on PortSwigger's DOM XSS in document.write sink using source location.search lab.

We can automatically enumerate Sinks using the DOM Invader extension within Burp's Chromium browser (Figure 4).

A Sink is a point in the web application where data is inserted into the or executed as code. Sinks are the locations in the code where the untrusted input data can potentially cause malicious scripts to run if not properly sanitized. Examples of common sinks include:innerHTML, outerHTML, document.write, etc.

Figure 4: Using DOM Invdader to enumerate sinks.

DOM Invader was able to identify a Sink associated with document.write. We can find more about it when we click the Stack Trace link (Figure 5.3) as well as exploit it by clicking on the Exploit button (Figure 5.4).

Figure 5: Using DOM Invader's features to find more about the Sink as well as exploit it.

Code Review

The example below is based on PortSwigger's DOM XSS in document.write sink using source location.search inside a select element lab.

The response of the application's /product directory contains an interesting piece of code (Figure 6).

Figure 6: Inspecting the application's front-end code.

If we manipulate the storeId parameter, we notice that it ends up within a select statement (Figure 7).

Figure 7: Manipulating the storeId parameter.

We can terminate the select statement and then pass our payload to achieve XSS (Figure 8).

// the JavaScipt payload used
</select><img src=x on error=alert()>
Figure 8: Achieving DOM-based XSS.

Last updated

Was this helpful?