DOM-based cross-site scripting
What is DOM-based cross-site scripting?
DOM-based cross-site scripting is a type of cross-site scripting (XSS) where the attack takes advantage of the Document Object Model (DOM).
How does DOM-based cross-site scripting work?
The Document Object Model is what makes dynamic, single-page applications possible. However, it is also what makes DOM-based cross-site scripting possible.
Unlike all other types of cross-site scripting, DOM-based XSS is purely a client-side vulnerability. This means that during a DOM-based XSS attack, the payload never reaches the server. The entire attack happens in the web browser.
DOM-based XSS is similar to reflected XSS because no information is stored during the attack. A DOM-based XSS attack is also conducted by tricking a victim into clicking a malicious URL.
Sources and sinks in DOM-based cross-site scripting
Every DOM-based XSS vulnerability has two elements: the source of user input and the target where this user input is written, called a sink. Popular sources that attackers can manipulate are
document.referrer. Popular sinks are
execScript. Note that this list is not exhaustive and many other sources and sinks also exist.
Example of DOM-based cross-site scripting
In this example, the developer wants to display the name of the user on the dashboard page (dashboard.html). The name of the user is passed to the application as a parameter in the URL:
<html> (...) Dashboard for <script> var pos=document.URL.indexOf("context=")+8; document.write(decodeURIComponent(document.URL.substring(pos))); </script> (...) </html>
The inline script looks for
context= in the URL (
document.URL.indexOf("context=")), takes all the text to the right of it (
+8 means 8 characters to the right of the beginning of
context=), and uses
document.write to insert that text directly into HTML to be interpreted by the browser.
If you call the following URL:
the page will say:
Dashboard for Thomas
The DOM-based cross-site scripting attack
The attacker creates the following URL:
http://www.example.com/dashboard.html?context= %3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%22%4c%45 %41%56%45%20%54%48%49%53%20%50%41%47%45%21%20%59%4f %55%20%41%52%45%20%42%45%49%4e%47%20%48%41%43%4b%45 %44%21%22%29%3b%3c%2f%73%63%72%69%70%74%3e
The long string of hex codes in this payload is a URL-encoded form of the following content:
<script>alert("LEAVE THIS PAGE! YOU ARE BEING HACKED!");</script>
Then, the attacker sends the URL to the victim, for example, in an email or instant message. The victim clicks the URL, causing their browser to open the dashboard.html page and run the malicious script. This rewrites the document content and inserts the following tag into the HTML interpreted by the browser:
Dashboard for <script>alert("LEAVE THIS PAGE! YOU ARE BEING HACKED!");</script>
As a result, the browser displays a pop-up window urging the user to leave the page. The consequences are that targeted users will stop visiting the web application, fearing for their safety.
Informed of the vulnerability, the developer rewrites the code using a safe sink. As a result, untrusted content from the source will always be interpreted as text, not code:
<html> (...) Dashboard for <span id="contentholder"></span> <script> var pos=document.URL.indexOf("context=")+8; document.getElementById("contentholder").textContent = document.URL.substring(pos,document.URL.length); </script> (...) </html>
The developer creates a placeholder object and writes the user’s name not into HTML directly but into the
textContent property of the placeholder object (using a safe sink). This guarantees that the browser won’t interpret this content as code and will simply display it as text.
Consequences of DOM-based cross-site scripting attacks
DOM-based cross-site scripting vulnerabilities are not very common but the consequences of a successful attack can be as dire as those of other reflected XSS attacks. Here are some actions that a black-hat hacker could perform based on the simple example presented earlier:
- They could create a phishing campaign and send millions of emails containing a malicious link with a payload that redirects users to a phishing page designed to mimic your web application. As a result, millions of users could potentially have their credentials stolen and blame your web application, which would severely damage your reputation.
- They could create a payload that sends the user to a malicious page that imitates your application’s login page. Then, they could send this malicious URL to your internal users, even your CEO. If even one of your users falls for the trick, the attacker will obtain their credentials to escalate the attack. Ultimately, this could let malicious actors gain access to other computer systems in your organization.
How to detect DOM-based cross-site scripting vulnerabilities
How to prevent DOM-based cross-site scripting vulnerabilities
<div> element, don’t use
innerHtml. Instead, use
Note that not all DOM elements have a safe output method. There are cases when you must simply avoid using untrusted data. For example, you must never write any untrusted data to sinks such as
How to mitigate DOM-based cross-site scripting vulnerabilities
Unlike other cross-site scripting vulnerabilities, you cannot mitigate DOM-based XSS using a web application firewall (WAF) or generic framework protection like request validation in ASP.NET. Such mechanisms are completely useless against DOM-based XSS attacks because the payload never reaches the server.
There is no way to mitigate or temporarily prevent zero-day DOM-based XSS attacks other than paying attention to the code of your web applications, scanning all your applications as often as possible, and keeping your third-party applications updated.
Frequently asked questions
What is DOM-based XSS?
DOM-based cross-site scripting is a type of cross-site scripting (XSS) attack executed within the Document Object Model (DOM) of a page loaded into the browser. A DOM-based XSS attack is possible if the web application writes data to the DOM without proper sanitization.
How dangerous is DOM-based XSS?
DOM-based XSS is only possible in specific cases but it is considered especially dangerous because it is difficult to detect and mitigate against. Since DOM-based XSS does not involve the server side of the application, web application firewalls cannot protect against it at all so there is no easy way to avoid zero-day DOM XSS attacks.
How to prevent DOM-based XSS vulnerabilities?