Skip to main content
Blog
Blog security

What Is DOM-Based XSS? How DOM Cross-Site Scripting Works

DOM-based XSS is a cross-site scripting attack where the vulnerability lives entirely in client-side JavaScript: the page's own code reads attacker-controlled input and writes it into the DOM unsafely. This guide explains how it differs from reflected and stored XSS, common sources and sinks, and how to detect it.

Aug 18, 2026 3 min read
What Is DOM-Based XSS? How DOM Cross-Site Scripting Works
Table of Contents

DOM-based XSS is a cross-site scripting vulnerability that lives entirely in client-side code. The page's own JavaScript reads attacker-controllable input, most often from the URL, and writes it into the DOM through an unsafe sink like innerHTML, executing the attacker's script. Unlike reflected or stored XSS, the malicious payload may never appear in any server response.

TL;DR: the XSS class servers never see

  • What it is: A cross-site scripting flaw living entirely in client-side JavaScript, where the page's own code writes attacker-controlled input into the DOM unsafely.
  • Why it hides: The payload often rides in the URL fragment, which is never sent to the server, so WAFs and server logs can miss it entirely.
  • Detection: Auditing source-to-sink data flows plus watching real sessions at the browser layer, the only place a DOM-only attack is visible.

Short on time? See cside client-side monitoring. It observes real sessions at the browser layer, where a DOM-only attack becomes visible.

How does a DOM XSS attack work?

The vulnerability is a data flow from a source the attacker controls to a sink that interprets text as code or markup:

// vulnerable: fragment flows straight into a sink
const name = decodeURIComponent(location.hash.slice(1));
document.querySelector("#welcome").innerHTML = "Hello " + name;
// https://example.com/#<img src=x onerror=stealCookies()>

Common sources: location.hash, location.search, document.referrer, window.name, postMessage data, and client-side storage. Common sinks: innerHTML/outerHTML, document.write, eval and Function, jQuery's .html(), and attribute writes that create handlers or URLs (onclick, href with javascript:).

Because the URL fragment is never sent to the server, a payload after # can exploit the page while the server sees a perfectly normal request.

Reflected vs stored vs DOM-based XSS

Reflected XSSStored XSSDOM-based XSS
Where the payload livesIn the request, echoed by the serverIn the server's databaseIn client-side input (often the URL fragment)
Server response contains payload?Often ✗
Visible to WAFs / server logsUsuallyUsuallyOften not
Fixed whereServer-side output encodingServer-side sanitization + encodingClient-side code: safe sinks, sanitization

Why DOM XSS is easy to miss

Server-side defenses inspect requests and responses; DOM XSS can bypass both. Frameworks reduce the risk, React and friends escape by default, but dangerouslySetInnerHTML, template misuse, and the third-party scripts on the page reintroduce it. And a modern page runs dozens of scripts you did not write: an unsafe sink in any of them is an unsafe sink on your page. That composition problem is the core of client side security.

How to prevent and detect it

  • Prefer safe sinks: textContent over innerHTML; avoid eval and string-built handlers entirely.
  • Sanitize when HTML is unavoidable (DOMPurify or the emerging Sanitizer API), and adopt Trusted Types where supported. It turns unsafe sink writes into policy violations.
  • Deploy a strict Content Security Policy with nonces; it blocks many payload styles, though not the whole class.
  • Watch runtime behavior: exploitation ultimately manifests as scripts doing things they should not: new outbound requests, DOM writes into payment forms, unexpected listeners. cside's client-side monitoring observes real sessions at the browser layer, which is the only place a DOM-only attack is visible at all.
Simon Wijckmans
Founder & CEO

Founder and CEO of cside. Previously a product manager on Cloudflare Page Shield (now Cloudflare Client-Side Security). Co-chair of the W3C Anti-Fraud Community Group and a Forbes 30 Under 30 honoree. Building accessible security against client-side attacks, web security is not an enterprise-only problem.

FAQ

Frequently Asked Questions

In reflected XSS the malicious payload travels to the server and comes back embedded in the HTML response. In DOM-based XSS the server response can be completely clean: the page's own JavaScript reads the payload from a client-side source (often the URL fragment, which is never sent to the server) and injects it into the DOM. That is why server-side filters and WAFs, which inspect requests and responses, can miss DOM XSS entirely.

It helps but does not close the class. A strict Content Security Policy blocks inline script injection and untrusted sources, which defeats many payloads. But DOM XSS executed through an allowlisted script's own unsafe sink, or a payload that abuses a permitted framework feature, stays within policy. CSP is a strong layer; it is not a substitute for fixing unsafe sinks or watching what scripts actually do at runtime.

Statically, by auditing code paths from sources (location.hash, location.search, document.referrer, postMessage data) to sinks (innerHTML, document.write, eval, setAttribute of event handlers). Dynamically, with DOM-aware scanners and by monitoring real sessions for unexpected script behavior. The vulnerability only exists in the browser, so browser-layer visibility is where exploitation becomes observable.

Monitor and Secure Your Third-Party Scripts

Gain full visibility and control over every script delivered to your users to enhance site security and performance.

Start free, or try Business with a 14-day trial.

cside dashboard interface showing script monitoring and security analytics
Related Articles
Book a demo

Want to walk through this with an engineer?

Thirty minutes, on your own site. Not a slide deck.

Book a personalized demo to see:

How to achieve PCI DSS requirement 6.4.3 & 11.6.1 compliance in 1 day
Why third-party scripts are a security risk for you and your visitors
Monitoring privacy and consent leakage (GDPR, CCPA) across every third party
Stopping signup abuse, account sharing, and chargeback fraud with device intelligence
Detecting and controlling AI agents and bots hitting your site in real time

Rather just send a question?

Finding open slots…

Real humans only. We'd know.

Having trouble booking? Open scheduler in a new tab

What are you trying to solve?

Tell us in a line and we'll come back with something useful, not a generic pitch.

We usually help with:

Seeing which third-party scripts run on your site
PCI DSS 6.4.3 and 11.6.1 evidence
Bots, AI agents and account takeover

Prefer to just book a time? Pick a slot instead