DOM-based Cross-site Scripting (DOM XSS) is a particular type of a Cross-site Scripting vulnerability. It uses the Document Object Model (DOM), which is a standard way to represent HTML objects in a hierarchical manner. As with all other Cross-site Scripting (XSS) vulnerabilities, this type of attack also relies on insecure handling of user input on an HTML page. It is particularly common when applications leverage common JavaScript function calls such as document.baseURI to build a part of the page without sanitization.

This type of attack is explained in detail in the following article: DOM XSS: An Explanation of DOM-based Cross-site Scripting. For more information on other types of XSS attacks: reflected XSS and stored XSS, see the following article: Types of XSS: Stored XSS, Reflected XSS, and DOM-based XSS.

An Example of DOM XSS

One of our Vulnweb test sites features a DOM-based XSS vulnerability that can be exploited using the following payload:

http://testhtml5.vulnweb.com/#/redir?url=javascript:alert("DOM XSS on: " + document.domain)

The result can be seen in the following image. It is an informational message with a simple alert. Note how the payload is stored in the GET request, making it suitable for social engineering attacks.

DOM XSS

The payload can be manipulated to deface the target application using a prompt that states: Your session has expired. Please insert your password to refresh your session. It is a simple yet effective way to harvest passwords using only the victim’s browser.

DOM XSS

The #redir route is executed by another file, redir.html. View the source code of this file and note the following JavaScript code snippet:

<script>
    var redirUrl = decodeURIComponent(window.location.hash.slice(window.location.hash.indexOf("?url=")+5));
    if (redirUrl) window.location = redirUrl;
</script>

Essentially, the exploit uses the window.location.hash source, which is evaluated in an HTML element sink. For information on sources and sinks, read the following article: Finding the Source of a DOM-based XSS Vulnerability with Acunetix.

How To Prevent DOM XSS

The primary rule that you must follow to prevent DOM XSS is: sanitize all untrusted data, even if it is only used in client-side scripts. If you have to use user input on your page, always use it in the text context, never as HTML tags or any other potential code.

Avoid methods such as document.innerHTML and instead use safer functions, for example, document.innerText and document.textContent. If you can, entirely avoid using user input, especially if it affects DOM elements such as the document.url, the document.location, or the document.referrer.

Also, keep in mind that DOM XSS and other types of XSS are not mutually exclusive. Your application can be vulnerable to both reflected/stored XSS and DOM XSS. The good news is that if user input is handled properly at the foundation level (e.g. your framework), you should be able to mitigate all XSS vulnerabilities.

How To Detect DOM XSS

It is almost impossible to detect DOM XSS only from the server side (using HTTP requests). Most DOM XSS payloads are never sent to the server because they are prepended by the symbol. This means, that no data will be available in server logs. This fact makes it more difficult to maintain web application security.

To detect the possibility of a DOM XSS, you must simulate the attack from the client-side in the user’s browser using a web application scanner like Acunetix. Acunetix uses its DeepScan technology to attempt DOM XSS against the client-side code and report vulnerabilities.

DOM-based XSS Cheat Sheet

For more details on how to prevent DOM-based XSS attacks, you can read the OWASP DOM-based XSS Prevention Cheat Sheet.

Source: https://www.acunetix.com/blog/web-security-zone/