Platform

Platform overview How it works Authorization testing Evidence & reports Private scanning Integrations

Solutions

Security agencies Product teams Regulated industries Partner programme

Learn

Blog Knowledge hub Compare

Resources

Pricing Documentation Help centre FAQ Security & data What we haven’t proved

Company

About Contact Careers Sign in to the platform Start a $199 pilot →

Home / Knowledge hub / DOM-based XSS

Knowledge hub

DOM-based XSS

Script injection that happens in the browser's own code, not in the server's response.

Illustration explaining DOM-based XSS

What it means

DOM-based XSS is a form of cross-site scripting where the unsafe step happens in the browser. Your page's own JavaScript takes data from an attacker-controlled source, such as the URL fragment or location.search, and writes it into a dangerous sink, such as innerHTML, document.write or eval.

The server may never see the payload. A fragment after # is not sent to the server at all, so the response looks clean and server-side filters and logs have nothing to catch. That is what separates it from reflected and stored cases.

Why it matters

A successful injection runs script in your origin with the visitor's session. It can read the page, make requests as that visitor and change what they see. For a single-page app the whole interface is built in the browser, so the exposure can be wide.

It is also easy to miss. Server-side scanners, a web firewall and code review of back-end templates all look in the wrong place. Modern front-end frameworks escape most output by default, so the problems tend to sit in the places where a developer chose to bypass that, for speed or for a rich-text feature.

How it shows up

You meet it in search boxes that update the page without a reload, in code that reads location.hash to pick a tab, in templates that build HTML from strings, and in third-party widgets. In frameworks, look for the escape hatches: dangerouslySetInnerHTML in React, v-html in Vue, bypassSecurityTrust in Angular.

Fixes follow one rule: put untrusted data into the page as text, not as markup. Use textContent, not innerHTML. Where HTML is needed, sanitise it with a maintained library. Add Trusted Types and a content security policy as a second layer, not as the first.

Questions people ask

DOM-based XSS, answered

How is DOM-based XSS different from reflected XSS?

In reflected XSS the server puts the input into its response. In the DOM case the browser-side code does it, so the server may never see the payload. The effect on the visitor is the same.

Can a web application firewall stop DOM XSS?

Rarely. If the payload sits in the URL fragment, it never reaches the firewall. Fix the code that writes the data into the page instead.

What are sources and sinks?

A source is where untrusted data enters browser code, such as the URL, document.referrer or postMessage. A sink is a function that turns data into code or markup. DOM XSS needs a path from one to the other.

Does using React or Vue make us safe?

It makes the common case safe, because output is escaped by default. Risk returns where you use raw-HTML features, build URLs from user input, or pass data to eval-like functions.

How do we test for it?

Review the front-end code for risky sinks, and test in a real browser with payloads in the URL, fragment and stored values. Static reading finds candidates; execution in a browser proves which ones fire.

Cyberlop mark

Does the script run in a real browser?

We drive the running app in a browser and, in white-box mode, read the code to point to the line, so a DOM XSS finding is one that actually fired. Book a pilot on one app.

Or start with a $199 pilot on one application: thirty days, success criteria agreed before day one, credited against the annual if you convert.