The DOM (Document Object Model) is how a web browser represents a webpage as a tree of elements like text, buttons, images, and forms. DOM-based vulnerabilities arise when a website contains JavaScript that takes an attacker-controllable value, known as a source, and passes it into a dangerous function, known as a sink.
Sources A source is where data or input comes from in a website or application. It can be user input, a URL, a form, or data provided by the developer. It’s where attacker-controlled input comes from.
Sinks A sink is where the data goes or is used in the website. Some sinks are dangerous because they can execute or process attacker-controlled input in an unsafe way.
➜ 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.
➜ A DOM XSS attack doesn't need the malicious input to reach the server. The attacker can put the payload in the URL, and when the victim opens the link, JavaScript processes the input directly in the browser.
Flow: Attacker → Malicious Link → Victim's Browser → JavaScript → XSS
The following are typical sources that can be used to exploit a variety of taint-flow vulnerabilities:
document.URL
document.documentURI
document.URLUnencoded
document.baseURI
location
document.cookie
document.referrer
window.name
history.pushState
history.replaceState
localStorage
sessionStorage
IndexedDB (mozIndexedDB, webkitIndexedDB, msIndexedDB)
Database
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 |
| JavaScript injection | eval() |
| Document-domain manipulation | document.domain |
| WebSocket-URL poisoning | WebSocket() |
| Link manipulation | element.src |
| Web message manipulation | postMessage() |
| Ajax request-header manipulation | setRequestHeader() |
| Local file-path manipulation | FileReader.readAsText() |
| Client-side SQL injection | ExecuteSql() |
| HTML5-storage manipulation | sessionStorage.setItem() |
| Client-side XPath injection | document.evaluate() |
| Client-side JSON injection | JSON.parse() |
| DOM-data manipulation | element.setAttribute() |
| Denial of service | RegExp() |