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.

Application securityUpdated July 20, 2026
Also known asDOM XSSClient-side XSSType-0 XSS

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

1

Untrusted data enters a source

The browser exposes attacker-influenced values such as location.hash or postMessage payloads.

2

Application JavaScript reads the source

First-party or third-party scripts parse the value for routing, previews, or UI state.

3

Data reaches an unsafe sink

The value is assigned to innerHTML, document.write, eval-like APIs, or risky URL sinks.

4

Browser interprets active content

Injected markup or script executes in the origin’s privilege context.

5

Attacker achieves impact

Session abuse, data theft, or in-origin phishing follows—same consequences as other XSS.

Sources and sinks

CategoryExamples
Sourceslocation.*, document.URL, referrer, postMessage, window.name, localStorage reads
HTML sinksinnerHTML, outerHTML, insertAdjacentHTML, document.write
JavaScript sinkseval, Function, setTimeout/setInterval with strings
URL / navigation sinkslocation, 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

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.

Browse glossary