Scan JavaScript for DOM-Based XSS Risks

Enter a page that loads the client application. Scan.now reviews inline and same-origin scripts for browser-controlled inputs paired with dangerous HTML or code-execution sinks.

Enter the exact public page to inspect. No form is submitted and no data is modified.

A registered account is required to run this test. Finding status, evidence, affected locations and remediation are Premium-only. How active scanning works · Acceptable use

Finding the two halves of a DOM XSS data flow

DOM-based XSS happens entirely in client-side code. JavaScript reads attacker-influenced data from a source such as location.search, location.hash, document.referrer, storage or postMessage, then passes it to a sink that interprets text as HTML or code.

Scan.now reviews inline scripts and a bounded set of same-origin JavaScript files for recognised sources and dangerous sinks. When both appear, it reports a candidate for developer review. Static proximity is not proof that data flows between them, so this check deliberately reports information rather than claiming confirmed exploitation.

Browser-controlled sources and dangerous sinks

The check is deliberately bounded to the signals below.

Coverage areaWhat the scanner examines
Browser-controlled sourcesURL components, referrer, web messaging and browser storage APIs are recognised as places untrusted data can enter.
HTML and code sinksinnerHTML, outerHTML, insertAdjacentHTML, document.write, eval, Function and string-based timers are highlighted.
Same-origin script sampleInline code and up to eight referenced same-origin scripts are inspected; raw source is not retained in the report.

Candidate data flows and clean static reviews

A scan result is evidence with a boundary, not a guarantee about every route.

Candidate found

At least one source and one sink exist in the inspected code. Trace the specific value through assignments, transformations and framework helpers.

No pair found

The sampled scripts did not contain a recognised source-and-sink combination. Bundling, dynamic imports and framework abstractions can hide flows.

Not a confirmation

A candidate may be safe because the values never meet or are sanitised. Browser-led data-flow testing is needed before calling it exploitable.

Safe DOM construction and trusted data boundaries

Use the recommendations below to address confirmed findings and strengthen the surrounding control.

  1. Use text-only DOM APIs

    Assign untrusted text with textContent and create elements and attributes through DOM methods rather than HTML strings.

  2. Sanitise unavoidable HTML

    Use a maintained allow-list sanitizer at the final insertion point and keep its configuration narrow.

  3. Validate postMessage origins

    Check event.origin against exact trusted origins and validate the message schema before using any field.

  4. Adopt Trusted Types

    In supported browsers, require trusted types for script sinks and centralise the few audited policies that may create HTML.

  5. Use CSP as containment

    A strict nonce-based policy reduces exploitability and produces violation reports, but does not repair the unsafe data flow.

How it works

  1. Enter a client-application page

    Use a page that loads the JavaScript bundle or feature you want reviewed.

  2. Sources and sinks are inventoried

    Inline code and bounded same-origin scripts are searched without executing them.

  3. Developers trace candidates

    The report names the APIs found and clearly separates a review candidate from confirmed reflected XSS.

What this tool checks

1 checks across 1 areas. Each links to its reference page with the test, the risk and the fix.

Full reference

Page content and JavaScript

1 check

The ones that most often decide the grade:

Guides for this tool

Background reading written to go with these results.

Frequently asked questions

What is the difference between reflected and DOM XSS?

Reflected XSS arrives in the server's HTML response. DOM XSS is created by browser-side JavaScript after the response, sometimes using only a URL fragment the server never receives.

Why is a source and sink pair not proof?

They may be in unrelated functions, behind unreachable branches or connected only after correct sanitisation. Static pattern matching identifies where human review is valuable.

Is innerHTML always vulnerable?

No. Constant trusted markup can be safe, and rigorously sanitised content can be acceptable. It is dangerous when attacker-controlled data can reach it without the right policy.

Does the scanner execute my JavaScript?

No. It reads a bounded amount of inline and same-origin source. Runtime-only bundles and behaviour after interaction require browser testing.