DOM XSS: What Is DOM-based Cross-Site Scripting And How can you Prevent it?

DOM XSS stands for Document Object Model-based Cross-site Scripting. This kind of XSS attack occurs when an application receives some client-side JavaScript that processes data from an unsafe, or untrusted source by writing the data to a potentially dangerous sink within the DOM instead of writing data in HTML which would present a regular XSS.

What is DOM?

The Document Object Model is a programming interface that gives developers the ability to access the document (webpage) and manipulate it by executing operations, therefore this interface defines the structure of documents by connecting the scripting language to the actual webpage.

A Simple Example of a DOM XSS attack

As an example the following HTML page (vulnerable.site/welcome.html) contains this content:

<HTML>
<TITLE>Welcome!</TITLE>
Hi
<SCRIPT>
var pos=document.URL.indexOf("name=")+5;
document.write(document.URL.substring(pos,document.URL.length));
</SCRIPT>
<BR>
Welcome

</HTML>

Normally, this HTML page would be used for welcoming the user, e.g.:
http://www.vulnerable.site/welcome.html?name=Joe

However, a request such as the one below would result in an XSS condition:
http://www.vulnerable.site/welcome.html?name=
<script>alert(document.cookie)</script>

What are Source & Sink?

1. The victim’s browser receives this link, sends an HTTP request to www.vulnerable.site, and receives the above (static!) HTML page.

2. The victim’s browser then starts parsing this HTML into DOM. The DOM contains an object called document, which contains a property called URL, and this property is populated with the URL of the current page, as part of DOM creation.

3. When the parser processes the Javascript code, it executes it and it modifies the raw HTML of the page. In this case, the code references document.URL, and so, a part of this string is embedded at parsing time in the HTML.

4. The string is then parsed and the Javascript code (alert(…)) is executed in the context of the same page, hence the XSS condition.

The logic behind the DOM XSS is that an input from the user (source) goes to an execution point (sink). In the previous example, our source was document.write and the sink was alert(document.cookie). 

After the malicious code is executed by the website, you can simply exploit this DOM-based cross-site scripting vulnerability to steal the cookies from the user’s browser or change the behavior of the page on the web application as you please.

How Do Attackers Exploit DOM XSS Vulnerabilities?

Source

A source is a JavaScript property that contains data that an attacker could potentially control:

document.URL
document.referrer
location
location.href
location.search
location.hash
location.pathname

Sink

A sink is a DOM object or function that allows JavaScript code execution or HTML rendering.

eval
setTimeout
setInterval
document.write
element.innerHTML

Any application is vulnerable to DOM-based cross-site scripting if there is an executable path via which data can develop from source to sink.

If you want to know more about how DOM-XSS attacks work, check out this article:

how dom xss attacks work


Different sources and sinks have various properties and behaviors that can impact exploitability, and determine what methods are used. Additionally, the application’s scripts might execute validation or other processing of data that must be accommodated when aiming to exploit a vulnerability.

In reality, the attacker would encode the URL payload so the script is not visible. Some browsers, for example, Mozzila may automatically encode the < and > characters in the document.URL when the URL is not directly typed in the address bar, and therefore it is not vulnerable to the attack shown in the example above. 

Embedding a script directly in the HTML is just one attack access point, other scenarios do not require these characters, nor embedding the code into the URL directly. Therefore, browsers in general are not entirely immune to DOM XSS either.

Execution flow of DOM-based XSS attacks

Execution flow of DOM-based XSS attacks

Defending Against DOM XSS Attacks

DOM XSS attacks are hard to detect from the server-side, because malicious payloads typically do not reach the server and hence cannot be sanitized in the server-side code. 

The root of the problem resides in the code of the page, this time in client-side code. 

The same prevention techniques used for other XSS attacks can be used. The only difference is that in the case of DOM XSS, you must review and sanitize client-side code, not server-side code.

You can try the following techniques in order to defend against DOM XSS:

– Avoid using data received from the client for client-side sensitive actions such as rewriting or redirection.

– Sanitize client-side code by inspecting references to DOM objects that pose a threat, for example, URL, location, and referrer. This is especially important if DOM can be modified.

– Use intrusion prevention systems that can inspect inbound URL parameters and prevent the inappropriate pages to be served.

Get the Latest Application Security News and Content

SUBSCRIBE

Scale up efforts and set the new standard of integrating security into modern development!