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:
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.
<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.textContent. If you can, entirely avoid using user input, especially if it affects DOM elements such as the
document.location, or the
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.