DOM-based XSS involves the execution of a payload as a result of modifying the DOM inside the browser used by a client side script. Since the payload resides in the DOM, the payload may not necessarily be sent to the web server.
Sources and Sinks
In order to understand how DOM-based XSS vulnerabilities work, one must first understand the difference between sources and sinks.
The source is the property that is read from the DOM. This is the property where a script can be injected to exploit a DOM XSS vulnerability. The sources listed hereunder are amongst some of the DOM properties that are most commonly exploited for DOM-based XSS.
|Source Name||Property susceptible to DOM-based XSS|
|Location / Document URL / URL||
|Sink Name||Property susceptible to DOM-based XSS|
|HTML Element Sink||
|Set Location Sink||
document.location and its properties can be both a source as well as a sink.
A Simple Example of DOM-based XSS
The following example is taken from OWASP’s DOM-based XSS article, and shall be used to demonstrate how DOM-based XSS is detected by Acunetix WVS. A more advanced, harder to detect example of DOM-based XSS is covered further on in this article.
The following HTML markup can be used to allow users to select a default language.
<html> <head><title>DOMXSS</title></head> </body> Select your language: <select><script> document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>"); document.write("<OPTION value=2>English</OPTION>"); </script></select> </body> </html>
The above markup renders the default language by making use of the query string. For instance, the following URL includes the parameter “German” in the query string.
Running a scan with Acunetix WVS on such a page will detect a DOM-based XSS vulnerability as indicated below.
Reproducing this vulnerability is straightforward since the source of this DOM-based XSS vulnerability is actually in the Location which is an object in the DOM that can be used to get the current page address (URL). Therefore, considering the alert Acunetix WVS provides, by simply entering the following URL inside of a browser, the vulnerability is exploited since anything that is entered in the URL’s query string is being echoed back into the page (in the <select> control) without being sanitized first.
Note – This example may not work in some browsers due to built-in XSS prevention mechanisms.
A More Advanced Example of DOM-based XSS
While the example above is rather straight forward to understand and fix, some DOM-based XSS vulnerabilities are generally more complex to identify.
The screenshot below is taken from an Acunetix WVS scan of http://testhtml5.vulnweb.com. Under Attack Details, Acunetix WVS lists useful information which can be used to find the source of the issue and reproduce the vulnerability manually.
The information presented in the Attack Details section shows the following:
- The Source of the vulnerability –
- The data input used by Acunetix WVS to identify and exploit this vulnerability – In this case, Acunetix WVS set
- The Execution Sink causing the data input to be executed – evaluate code section. Note that Acunetix WVS may not always determine the exact sink and will provide multiple possible Execution Sinks.
- The Evaluated code, which is the code that shows where the payload was outputted to the page or executed.
- The Stack Trace
With this information, it is now possible to identify and reproduce this vulnerability. The portion of the alert that details the source of the vulnerability provides an indication of which part of the DOM is being manipulated in the attack. In this case, the vulnerable parameter is
window.name, which can be exploited with the following code hereunder (pop-ups need to be enabled).
<html> <body> <script> window.open("http://testhtml5.vulnweb.com", "alert('DOM XSS');"); </script> </body> </html>
window.name source. However,
window.name is nowhere to be found in sessvars.js in the file. This will be explained further on, but first the Stack Trace provided by Acunetix WVS will be used to get more information.
Checking line 105 in sessvers.js, as indicated in the Stack Trace (since a Stack Trace is built from bottom-to-top), reveals the DOM-based XSS sink; which is in fact an
x which is in-turn being set by the
eval() is indeed one of the possible execution sinks that Acunetix WVS reports in the above alert.
When checking line 76, as per the Stack Trace, the
toObject function is being passed
top.name without any sanitization.
toObject is the function that contains the DOM-based XSS sink as described above.
While this may be slightly confusing at first, upon taking a closer look, one may notice that the property vulnerable to DOM-based XSS in sessvars.js is
top object returns the top-most browser window and is in fact inheriting properties from
window. This is the place where the source of the DOM XSS vulnerability is being read from the DOM.