In this section, we will describe what the DOM is, explain how insecure processing of DOM data can introduce vulnerabilities, and suggest how you can prevent DOM-based vulnerabilities on your websites.
Many DOM-based vulnerabilities can be traced back to problems with the way client-side code manipulates attacker-controllable data.
To either exploit or mitigate these vulnerabilities, it is important to first familiarize yourself with the basics of taint flow between sources and sinks.
Fundamentally, DOM-based vulnerabilities arise when a website passes data from a source to a sink, which then handles the data in an unsafe way in the context of the client's session.
The most common source is the URL, which is typically accessed with the location object. An attacker can construct a link to send a victim to a vulnerable page with a payload in the query string and fragment portions of the URL. Consider the following code:
goto = location.hash.slice(1)
location = goto;
This is vulnerable to DOM-based open redirection because the location.hash source is handled in an unsafe way. If the URL contains a hash fragment that starts with https:, this code extracts the value of the location.hash property and sets it as the location property of the window. An attacker could exploit this vulnerability by constructing the following URL:
The following are typical sources that can be used to exploit a variety of taint-flow vulnerabilities:
IndexedDB (mozIndexedDB, webkitIndexedDB, msIndexedDB)
The following kinds of data can also be used as sources to exploit taint-flow vulnerabilities:
The following list provides a quick overview of common DOM-based vulnerabilities and an example of a sink that can lead to each one. For a more comprehensive list of relevant sinks, please refer to the vulnerability-specific pages by clicking the links below.
|DOM-based vulnerability||Example sink|
|DOM XSS LABS||document.write()|
|Open redirection LABS||window.location|
|Cookie manipulation LABS||document.cookie|
|Ajax request-header manipulation||setRequestHeader()|
|Local file-path manipulation||FileReader.readAsText()|
|Client-side SQL injection||ExecuteSql()|
|Client-side XPath injection||document.evaluate()|
|Client-side JSON injection||JSON.parse()|
|Denial of service||RegExp()|
There is no single action you can take to eliminate the threat of DOM-based attacks entirely. However, generally speaking, the most effective way to avoid DOM-based vulnerabilities is to avoid allowing data from any untrusted source to dynamically alter the value that is transmitted to any sink.
For measures you can take to prevent specific vulnerabilities, please refer to the corresponding vulnerability pages linked from the table above.