DOM XSS
Cross-site scripting attacks in the document object model
JavaScript
What is DOM XSS?
Document Object Model (DOM) cross-site scripting (XSS) is a web application vulnerability that allows attackers to manipulate the DOM environment in a user's browser by injecting malicious client-side code. In contrast to reflected or stored XSS, where the vulnerability is caused by server-side flaws and the payload is reflected in the response, DOM XSS is purely client-side.
DOM XSS vulnerabilities are mainly attributed to situations where user-controllable sources pass data to sinks, such as eval()
, document.write
, or innerHTML
. These sinks allow for dynamic code execution.
Quick brief on the DOM
The DOM is an integral part of modern web applications, as it allows web applications to dynamically manipulate objects without making another trip back to the server. It works by representing data in nodes and objects for a web page in a hierarchical structure so that programming languages can interact with the page. The DOM's purpose is to allow web applications to modify their data by addressing each object on the page. Objects can be the actual content, styling or scripts, or data stored in a user’s browser that the website might need to access, such as cookies.
About this lesson
This lesson will build your fundamental knowledge about DOM XSS. We’ll walk through an example of exploiting DOM XSS vulnerabilities, we'll look at some vulnerable code, and how to fix the code to remove the vulnerability.
Zane is a new developer at the software company Friendy.io, a social media site for trendy friends. He’s just implemented a personalized color feature for users' profiles, to ensure that they have complete creative control over their brand.
Our job is to perform security assurance work on Zane's new feature. Let’s start testing and see if the new feature is vulnerable to DOM XSS.
In the previous example, we injected a malicious JavaScript code block into the website by escaping a query parameter. The function in the site that allowed this was modifying the DOM in an unsafe way; let’s explore what happened in more detail.
Most websites can receive dynamic data and update their content. When dangerous methods are used to achieve this, it can have unintended side effects that lead to security vulnerabilities. Sites also tend to store a plethora of information in the session, mainly in the form of cookies. These may include advertising IDs, user preferences, login credentials, email addresses, and more.
This code uses the document.write
sink, which can create script elements. This is an executable path where untrusted user-supplied input can propagate from the URL query parameter to the DOM. Also, there is no validation or processing in place.
The best way to mitigate this particular example is to remove the document.write
method by assigning the color value directly to the document.body.style.color
property. This eliminates the ability to input executable code to the browser's sink.
Sometimes applications require the use of dangerous methods such as document.write
. In these cases, user-supplied input needs to be heavily sanitized through a combination of: JavaScript escaping HTML encoding URL encoding
As a general rule, all user-supplied input should be sanitized. We can sanitize the input from our example by using the node-esapi
library recommended by OWASP. For example:
Content Security Policy
Another method for mitigating DOM XSS vulnerabilities is to utilize the Content Security Policy (CSP) security settings that are built into all modern browsers. In particular, using "nonce" will thwart attackers from being able to inject their own script tags, although this mitigation method is not sufficient to protect against some types of DOM XSS vulnerabilities; notably when the user input is injected into pre-existing script tags.
More information about CSP can be found here.
Keep learning
- Learn more at Snyk about Cross-Site Scripting
- Check out this cheat sheet for more information
- OWASP has great documentation on DOM XSS
- Learn what Mozilla does to Fixing DOM XSS with Static Analysis