What Is DOM-Based XSS?
DOM-based XSS is a form of cross-site scripting where the entire vulnerable data flow lives in the browser. Client-side JavaScript reads attacker-influenced input and writes it into a dangerous sink that executes it — often without the payload ever reaching the server. That makes it invisible to server-side defenses and a favorite in modern single-page apps.
Sources and sinks#
DOM XSS is best understood as data flowing from a source to a sink:
| Sources (input) | Sinks (execution) |
|---|---|
location.hash, location.search | innerHTML, outerHTML |
document.URL, document.referrer | document.write |
postMessage data | eval, Function |
localStorage values | setAttribute on src/href |
The bug is any path where untrusted source data reaches a sink without safe handling. A
classic one-liner: reading location.hash and assigning it to element.innerHTML.
Why does it evade server defenses?#
Because the server may never see the payload. Data after the # in a URL is not even sent to the
server; postMessage and localStorage are purely client-side. A perfectly filtered backend and
a strict server-side CSP can still sit atop a page
that XSSes itself in JavaScript.
How do you prevent DOM XSS?#
- Avoid dangerous sinks — prefer
textContentoverinnerHTML; neverevaluntrusted data. - Use safe APIs — framework binding that escapes by default;
Trusted Typesto lock down sinks. - Validate the source — treat
hash,postMessage, and storage as hostile input.
DOM XSS is the client-side sibling of reflected and stored XSS. More at the Web Security hub.
Frequently asked questions#
What is DOM-based XSS?
DOM-based XSS is a cross-site scripting flaw where the vulnerable data flow happens entirely in the browser: client-side JavaScript takes attacker-controllable input (a source like location.hash) and writes it into a dangerous sink (like innerHTML) that executes it. The server may never see the payload, so server-side filtering misses it.
What are sources and sinks in DOM XSS?
A source is where untrusted data enters the page — location.hash, document.URL, referrer, postMessage. A sink is a function that can turn data into code or markup — innerHTML, document.write, eval, setAttribute on certain attributes. DOM XSS occurs when data flows from a source to a sink without safe handling.