DOM-based Cross-Site Scripting (XSS) Explained

What is DOM XSS?

In order to understand DOM XSS, we need to describe a bit what DOM is, and why is it relevant to this context.

The Document Object Model is a convention for representing and working with objects in an HTML document (as well as in other document types). Basically all HTML documents have an associated DOM, consisting of objects representing the document properties from the point of view of the browser. Whenever a script is executed client-side, the browser provides the code with the DOM of the HTML page where the script runs, thus, offering access to various properties of the page and their values, populated by the browser from its perspective.

DOM XSS is a type of Cross-site scripting attack which relies on inappropriate handling, in the HTML page, of the data from its associated DOM. Among the objects in the DOM, there are several which the attacker can manipulate in order to generate the XSS condition, and the most popular, from this perspective, are the document.url, document.location and document.referrer objects.

A Typical Example of a DOM XSS Attack

Let’s take the basic example of a page which provides users with customized content, depending on their user name which is encoded in the URL, and uses their name on the resulting page:

In this case the HTML of http://www.mywebsite.com/userdashboard.html would look like this:

<HTML>
<HEAD>
<TITLE>Custom Dashboard </TITLE>
…..
</HEAD>
Main Dashboard for 
<SCRIPT>
var pos=document.URL.indexOf("context=")+8;
document.write(document.URL.substring(pos,document.URL.length));
</SCRIPT>
…
</HTML>

The result of http://www.mywebsite.com/userdashboard.html?context=Mary would be a customized dashboard for Mary, containing the string “Main Dashboard for Mary” at the top.

The malicious script can be embedded in the URL as follows:

<script>

http://www.mywebsite.com/userdashboard.html?context=<script>SomeFunction(somevariable)

</script>

or

<script>

http://www.mywebsite.com/userdashboard.html#context=<script>SomeFunction(somevariable)

</script>

Further on, the victim’s browser receives the above URL and sends a HTTP request to http://www.mywebsite.com, receiving the static HTML page described above. Then, the browser starts building the DOM of the page, and populates the document.url property, of the document object with the URL containing the malicious script.

When the browser arrives to the script which gets the user name from the URL, referencing the document.url property, it runs it and consequently updates the raw HTML body of the page, resulting in “… Main Dashboard for <script>SomeFunction(somevariable)</script> …”.

Next, the browser finds the malicious code in the HTML body and executes it, thus finalizing the DOM XSS attack. In reality, the attacker would hide the contents of the payload in the URL using encoding so that it is not obvious that the URL contains a script.

Note however, that some browsers may encode the “<” and “>” characters in the URL, causing the attack to fail. However there are other scenarios which do not require the use of these characters, nor embedding the code into the URL directly, so these browsers are not entirely immune to this type of attack either.

How is DOM XSS different?

Using the above example, we can observe that:

  • The HTML page is static, and there is no malicious script embedded into the page, as in the case of other types of XSS attacks;
  • The script code never gets to the server, if the “#” character is used; it is seen as fragment and the browser does not forward it further. Hence server-side attack detection tools will FAIL to detect this attack; in some cases, depending on the type of the URL, the payload might get to the server and it may be impossible to hide it.

Hence, the main characteristics of XSS, as reviewed in the introduction of this article, are not valid in the case of DOM XSS. Instead, DOM XSS exploits inappropriate manipulation of the associated DOM objects and properties in the client-side code.

Defending against DOM XSS attacks

The DOM XSS attack is difficult to detect by server-side attack detection and prevention tools, because usually the malicious payload does not get to the server and hence cannot be sanitized in the server-side code, like in the case of other XSS attacks. However, since the root of the problem still resides in the code of the page, this time the client-side code, the same sanitization and prevention techniques apply, but in this case the code review as well as the implementation of sanitization functionality needs to be performed on the client-side code.

Effective conceptual defense methods against the DOM XSS include, but are not limited to:

  • Avoiding client-side sensitive actions such as rewriting or redirection, using client-side data;
  • Sanitization of the client-side code by inspecting and securely handling references to DOM objects that pose a threat, such as url, location and referrer, especially in cases when the DOM may be modified;
  • Using intrusion prevention systems which are able to inspect inbound URL parameters and prevent the inappropriate pages to be served.

Testing of the effectiveness of the sanitization methods in place, or for discovering the DOM XSS vulnerabilities can be performed by manually attempting to exploit them, or using automated tools that perform automatic penetration testing against this type of vulnerabilities, using various payloads and mounting points.

To summarize, this would be a comparison of classic Cross Site Scripting attacks vs DOM XSS attacks:

Attack CharacteristicClassic XSSDOM XSS
Root causeSource codeSource code
PremisesInappropriate embedding of client side data in outbound HTML pages (by the server)Inappropriate referencing and use in the client-side code, of DOM objects which are not entirely controlled and verified by the server-generated HTML pages
Page typeDynamicStatic or Dynamic
DetectionIntrusion detection systems, logsCannot be detected server side, if proper evading techniques are being used by the attacker.
Detection of vulnerabilitiesAttack simulation;
Code review – server-side;
Vulnerability detection tools that perform automatic penetration testing
Attack simulation;
Code review – client-side;
Vulnerability detection tools that perform automatic penetration testing
DefendingSanitization – server side
Intrusion prevention systems
Sanitization – client-side
Intrusion prevention systems –to a lesser extent
ShareShare on FacebookTweet about this on TwitterShare on Google+

Leave a Reply


*

  1. The only possibility of this attack is when the page uses part of the URI using DOM (JavaScript) i.e the malicious content is not part of the response.

    August 14, 2013 at 7:26 am Reply
    • Hi,

      You are correct. The website needs to include JavaScript that processes parts of the DOM (generally the URI) in a way that allows the attacker to inject his XSS script in the DOM, which will be then executed by the victim’s browser.

      August 14, 2013 at 8:15 am Reply
  2. hi… how can i verify/cross check DOM based XSS identified by the acunetix for its correctness

    December 3, 2013 at 10:21 am Reply
    • Hi,
      You should first use the information provided by Acunetix and try to manually reproduce the vulnerability using either the HTTP editor in Acunetix or a normal browser. Try different browsers, as browsers have been updated to prevent XSS code from being executed.

      Further verification and requires a good understanding of JavaScript, since you will need to find where the site’s JavaScript is reading the Source (i.e. where the XSS code is being read from the DOM), and at which stage it is being outputted on the page (aka the Sink).
      Acunetix will, in most cases, provide this information as part of the alert, however this may not always be possible due to the complexity of the JavaScript code.

      December 4, 2013 at 5:17 am Reply
  3. Pingback: Just Released Acunetix Online Vulnerability Scanner Beta Version

  4. Pingback: Finding the Source of a DOM-based XSS Vulnerability with Acunetix WVS | Acunetix

  5. Pingback: The Chronicles of DOM-based XSS | Acunetix

  6. Dhinakaran

    Hi,
    If I am right, sanitizing the part of string which is put on document.property(document.write) would fix the issue?

    April 17, 2014 at 4:23 pm Reply
    • Hi,

      Yes, ideally all data which is provided by the user and which is being used by the web application should be sanitize to avoid such issues.

      April 21, 2014 at 8:02 am Reply
  7. Pingback: 0×1 Exploit Tutorial: XSS ← Primal Security Podcast