Cybersecurity glossary
What is DOM-Based XSS?
Learn what DOM-based XSS is, how unsafe client-side JavaScript sinks create script injection without a classic server reflection, and how to find and prevent DOM XSS in modern web apps.
Definition
DOM-based XSS is a cross-site scripting vulnerability in which client-side JavaScript takes untrusted data from a source such as the URL and writes it into an unsafe sink in the Document Object Model, causing attacker-controlled script to run in the victim’s browser.
Why DOM-based XSS matters
Security reviews that only inspect server templates miss an entire class of bugs. DOM-based XSS lives in client-side code paths: routers, analytics helpers, debug panels, and custom HTML renderers. The malicious string may sit in a URL fragment that never reaches application logs, yet still executes when JavaScript reads it and writes it into the DOM unsafely.
As frontends grow richer, more XSS risk moves into the browser. Teams that treat XSS as a “server encoding problem only” leave SPA and mobile-webview attack surface untested.
How DOM-based XSS works
Untrusted data enters a source
The browser exposes attacker-influenced values such as location.hash or postMessage payloads.
Application JavaScript reads the source
First-party or third-party scripts parse the value for routing, previews, or UI state.
Data reaches an unsafe sink
The value is assigned to innerHTML, document.write, eval-like APIs, or risky URL sinks.
Browser interprets active content
Injected markup or script executes in the origin’s privilege context.
Attacker achieves impact
Session abuse, data theft, or in-origin phishing follows—same consequences as other XSS.
Sources and sinks
| Category | Examples |
|---|---|
| Sources | location.*, document.URL, referrer, postMessage, window.name, localStorage reads |
| HTML sinks | innerHTML, outerHTML, insertAdjacentHTML, document.write |
| JavaScript sinks | eval, Function, setTimeout/setInterval with strings |
| URL / navigation sinks | location, location.href, script.src, iframe.src with untrusted values |
Practical example pattern
A page reads location.hash to render a welcome banner:
document.getElementById('msg').innerHTML = location.hash.slice(1)
An attacker sends https://app.example/#<img src=x onerror=...>. The server may return identical HTML for every user. The XSS still fires because the client script creates the sink.
Prevention for DOM XSS
Prefer safe sinks
Use textContent, safe framework bindings, and vetted sanitizers instead of innerHTML with raw strings.
Encode by context
If concatenation is unavoidable, encode for HTML, attribute, or URL context explicitly.
Trusted Types
Where supported, enforce Trusted Types so only policy-created values can flow into dangerous sinks.
Strict CSP
Reduce exploitability of injected scripts while you eliminate unsafe code paths.
- Trace every read of location, postMessage, and storage into DOM update code.
- Ban or gate innerHTML and document.write in lint rules for application code.
- Sanitize HTML with maintained libraries only when rich markup is truly required.
- Validate postMessage event.origin before accepting data.
- Review third-party scripts that touch the DOM with page URL data.
- Include fragment-based payloads in XSS test cases and DAST configurations.
- Apply the same controls in embedded webviews as in primary browsers.
- Monitor CSP violation reports for clues about unsafe client sinks in production.
The practical takeaway
DOM-based XSS is XSS caused by unsafe client-side data flows from sources to sinks—often invisible to server logs. Impact matches other XSS: attacker script in a trusted origin.
Fix it by eliminating dangerous sinks, encoding correctly, adopting Trusted Types where practical, and testing JavaScript paths with the same seriousness as templates. If your SPA reads the URL and writes HTML, assume attackers will try to meet it halfway.
Related security terms
Cross-Site Scripting (XSS)
The broader XSS category that includes reflected, stored, and DOM-based variants.
Reflected XSS
Server-echoed XSS that often appears similar in impact but differs in where the bug lives.
Content Security Policy (CSP)
A browser policy that can reduce DOM XSS impact when strictly enforced.
Cross-Site Scripting (XSS)
Vulnerability deep dive covering XSS exploitation beyond this glossary definition.
Frequently asked questions
What is DOM-based XSS in simple terms?
DOM-based XSS is when a page’s own JavaScript unsafely takes data from the page URL or other client sources and inserts it into the page as code. The server may never see the malicious payload.
How is DOM XSS different from reflected XSS?
Reflected XSS requires the server to include the payload in HTML. DOM XSS happens in the browser when JavaScript mishandles data, even if the server response is static.
What are common DOM XSS sources?
location, location.hash, location.search, document.referrer, postMessage data, window.name, and client storage values read by application scripts.
What are common DOM XSS sinks?
innerHTML, outerHTML, document.write, eval, setTimeout with strings, jQuery html(), and some URL assignments like location or script.src.
Why do single-page apps still get DOM XSS?
SPAs move rendering into JavaScript. Routing, markdown renderers, and third-party widgets create many client-side sinks if developers bypass safe framework escaping.
Can CSP stop DOM XSS?
A strict CSP without unsafe-inline and with nonces/hashes can block many payloads, but unsafe sinks and allowed script gadgets may still enable exploitation. Fix the code.
How do you test for DOM XSS?
Use browser DevTools, DOM XSS scanners, and manual source-to-sink tracing. Pay special attention to fragments after # that servers never receive.
References
Explore authoritative guidance and frameworks related to dom-based xss.
Explore every security definition
Return to the glossary to search by term, alias, starting letter, or security category.