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.
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.
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 (with DOM-based XSS scanner functionality). 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.
Frequently asked questions
DOM-based cross-site scripting (DOM XSS) is a web vulnerability, a subtype of cross-site scripting. An attacker can execute a DOM-based cross-site scripting attack if the web application writes user-supplied information directly to the Document Object Model (DOM) and there is no sanitization.
Based on our research summarized in the Acunetix Web Application Vulnerability Report, DOM-based cross-site scripting is not very common – such vulnerabilities exist only in approximately 1.2% of analyzed web applications. Despite being rare, they may cause serious problems and only a few scanners can detect them.
Read the entire Acunetix Web Application Vulnerability Report.
It is difficult to detect DOM-based cross-site scripting because very often it leaves no mark on the server at all (for example, in server logs) – the whole attack happens in the client. It is also impossible to protect against such client-side attacks using WAFs. Your best bet is to use a vulnerability scanner with a DOM-based cross-site scripting detection module. For example, Acunetix.
To prevent DOM-based cross-site scripting, 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. Use only safe functions like document.innerText and document.textContent.
Get the latest content on web security
in your inbox each week.