Overview
DOM-based XSS is a variant where the vulnerability lives entirely in client-side JavaScript — the page's own script takes untrusted input and unsafely writes it into the page, without the server necessarily being involved. This lesson explains DOM XSS.
Learning objectives
- Define DOM-based XSS.
- Distinguish it from reflected/stored XSS.
- Identify the client-side source→sink pattern.
Core concept
DOM XSS occurs when client-side JavaScript reads attacker-controllable input (a source, such as part of the URL) and passes it to a dangerous sink (an API that writes to the page/DOM as HTML or executes code) without safe handling. The malicious script then runs in the browser. Unlike reflected/stored XSS, the unsafe operation happens in the browser's JavaScript, so the server may never see or reflect the payload — making it invisible to purely server-side analysis.
How it works
The page's JavaScript takes data from a source (e.g. the URL fragment, query string, or other client-controllable input) and inserts it into the DOM via a sink that interprets it as HTML or code. If the data is not safely handled before reaching the sink, script within it executes. Because this is a client-side data flow (source → sink), the defense is also client-side: avoid dangerous sinks, use safe DOM APIs that treat data as text, and encode/validate before insertion. Server-side output encoding alone does not fix a purely DOM-based flaw.
Practical example
A page reads a value from the URL fragment in JavaScript and writes it into the page using an API that parses HTML (an unsafe sink). If the value contains markup/script, it executes in the browser — even though the server just served a static page and never processed the value. The fix is to use safe DOM methods that insert the value as text (not HTML), and to validate/encode client-side. Identifying the source (URL fragment) and the sink (HTML-writing API) is how you find and fix DOM XSS.
Cybersecurity relevance
DOM XSS is increasingly important as applications do more in the browser (rich client-side JavaScript, single-page apps). It can be missed by testing that only inspects server responses, since the flaw is in client-side code. Defenders must audit JavaScript for untrusted sources flowing into dangerous sinks, prefer safe DOM APIs, and apply CSP. Testers analyze client-side data flows. Understanding the source→sink model is key to recognizing and remediating this variant.
Common mistakes
- Assuming server-side encoding fixes DOM XSS — the unsafe operation is in client-side JS.
- Using DOM sinks that parse HTML for untrusted data instead of text-only APIs.
- Testing only server responses, missing purely client-side flows.
Key takeaways
- DOM-based XSS occurs when client-side JavaScript takes untrusted input (a source) into a dangerous DOM sink without safe handling, executing script in the browser.
- The flaw is in client-side code, so the server may never see the payload — server-side encoding alone does not fix it.
- Defend by avoiding dangerous sinks, using text-only/safe DOM APIs, validating/encoding client-side, and applying CSP; find it via source→sink analysis.
Check your understanding
- How does DOM-based XSS differ from reflected and stored XSS in where the unsafe operation happens?
- Why can server-side output encoding fail to prevent a DOM-based XSS flaw?

