Smart DOM XSS Detection in Qualys WAS

Vaagn Toukharian

Last updated on: December 20, 2022

Recently Qualys extended the cross-site scripting (XSS) detection capabilities of Qualys Web Application Scanning (WAS) by adding a new mechanism for detecting DOM based XSS (DOM XSS) vulnerabilities. The new mechanism works in an automated manner with no special setup or knowledge requirements, enabling security teams to greatly reduce the risk from these typically hard-to-detect vulnerabilities. Because of the technique Qualys WAS uses, it also indicates the location in your code of any XSS bugs found, which is pretty convenient for your development teams.

To understand the significance to web application security teams, let’s take a deeper look at XSS and the special case of DOM XSS.

About XSS

There are three main forms of XSS vulnerabilities: reflected XSS, stored XSS and DOM XSS.

Reflected XSS is where faulty server-side code fails to validate/sanitize/filter user input, allowing malicious users to inject JavaScript that gets reflected from the server side and executed on the client side.

Stored XSS is where the malicious JavaScript is stored in the application and then served in an exploited page to all users visiting the page.

DOM XSS is where the injection point for the malicious JavaScript is the browser, as opposed to reflected and stored XSS where the injection point is the server. The malicious user injects JavaScript code by modifying the DOM (Document Object Model) or adding JavaScript code directly for execution. This is possible in part because complex JavaScript-based applications take bits of information from various places and process them. Sometimes that processing leads to the creation of DOM objects or direct JavaScript evaluation (execution) in the client.

Some examples below will shed light on how this can be done.

With any XSS, the attacker can perform a number of damaging actions, such as stealing session cookies, redirecting to unwanted/malicious websites, and more. So these are vulnerabilities you want to fix.

Challenges with Automated Detection

Leading web application vulnerability scanners all do a pretty good job of detecting reflected and stored XSS vulnerabilities. The classic XSS detection approach involves sending test payloads to the server and detecting the issues caused by server-side mishandling. But that does not work for DOM XSS because the server side code is not the issue here. The JavaScript code resides on the client side, and DOM XSS vulnerabilities in that code can be very difficult to detect. We have also found that DOM XSS is fairly common even among top web sites and apps with good security teams.

First a few definitions will help describe how DOM XSS works and shed light on how it can be detected.

Sources and Sinks

Sources: The source is the injection point for the malicious JavaScript. With DOM XSS, the sources are on the client. Payloads including malicious JavaScript code injected into sources with or without some processing could then reflect in the DOM or execute.

Examples of DOM XSS sources are document.URL, cookies, referer header.

Sinks: The sink is the reflection point that eventually executes (or helps with execution of) the malicious JavaScript injected through the source. These are usually locations on the DOM or Browser Object that can change and invoke code, or they are JavaScript routines that allow direct JavaScript execution.

Examples of easy-to-exploit sinks are eval, document.write, setTimeout.

Examples of DOM XSS Vulnerabilities

Here are three examples of DOM XSS vulnerabilities that show three types of injection points (sources) and how they result in sinks where the JavaScript is either reflected in the DOM or executed.

Example 1:

Example 1: document.cookie and document.write

In this case, the source of the DOM XSS vulnerability is document.cookie and the sink is document.write. The way to exploit this vulnerability would be to set a cookie that contains malicious JavaScript code, and then entice the victim to navigate to the page where the cookie’s content is reflected in the document body.

An example of such a cookie could be:

Set-Cookie: badCookie=<script>alert(1)</script> Path=/;

Example 2:

Example 2: document.url and document.write

In this case, the source of the DOM XSS vulnerability is document.URL and the sink is document.write. The way to exploit this vulnerability would be to set a malicious JavaScript code as a part of a fragment of the URL:;

Example 3:

Example 3: window.location.hash and eval

In this case, the source of the DOM XSS vulnerability is window.location.hash and the sink is eval. The way to exploit this vulnerability would be to set a malicious JavaScript code as a part of a fragment of the URL:;

Detection via Taint Propagation (phase 1)

To detect DOM XSS in Qualys WAS, we have done significant instrumentation of the browsing engine, especially the JavaScript execution engine, to detect the passage of strings from sources to sinks. This is known as the taint propagation method.

The greatest benefit of the DOM XSS detection method employed in Qualys WAS is that the taint propagation check is done during natural crawling and web application progression. That means there is no need to artificially simulate user interaction with the web application — the Qualys WAS crawler already does that.

Having internal knowledge of what is going on with the page on the JavaScript Engine level, Qualys WAS can make use of detailed information about the source and sink as well as intermediate function calls in the taint propagation path. All the strings passed from possible sources are tracked to see if they land on sinks. As a result we have a bit of information to play with.

Details of Possible DOM XSS Vulnerabilities via Taint Propagation:

Source:   location JS call stack:   function: element.innerHTML Sink:   element.innerHTML

The details similar to the one above are helpful as there are few details reported, but these are then used to dig a bit deeper in the phase 2.

Detection via Exploitation (phase 2)

Qualys WAS does not only rely on detection of the source-sink connection, but also via exploit backtrace. In this phase, the suspected vulnerability is checked with our smart exploitation sub-engine that tries to inject JavaScript into the sink and detects its execution. This engine provides backtrace details of the JavaScript execution on the spot where the DOM XSS was exploited, which tells the development team which code to rewrite.

Details of Reported DOM XSS Vulnerabilities:
Here is an example of data that could be collected by Qualys WAS via taint propagation:

Source:   cookie JS call stack:   function: document.write Sink:   document.write

And additional details that could be collected via exploit backtrace:

_exploit_dom_xss global code@ write@[native code] call@[native code] write global code@

As you can see, the exploit backtrack shows you specifically what calls are part of the exploit path, so you can rewrite them to avoid the reported vulnerability.

Detection Details

Vulnerability details are reported in QID 150076 and can be used by customers to identify faulty JavaScript code, so that their development teams can apply fixes. QID 150076 was reported with older versions of WAS, but now the QID has greater coverage and accuracy.

Fixing DOM XSS Vulnerabilities

Since Qualys WAS performs both taint propagation check and exploitation, it reports very few false positives. That’s because the exploitation check ensures that the vulnerability in question could be exploited.

XSS gets its number three ranking on the OWASP top 10 because it enables an attacker to inject malicious javascript/code into pages that they shouldn’t be able to, due to vulnerabilities in the the site or app. Extending Qualys WAS to accurately and consistently detect DOM XSS in addition to reflected and stored XSS gives security teams complete coverage of an important class of vulnerabilities.

Show Comments (1)


Your email address will not be published. Required fields are marked *