How to Find DOM XSS With Burp DOM Invader (Practical Workflow)
Reflected XSS scanners miss a lot of SPA bugs. The sink is innerHTML or location.hash handling five frames deep, and the server never echoed your payload. DOM Invader exists for that gap: it instruments the page, watches sources, and injects canaries.
I still verify every highlight by hand. The tool finds candidates; you prove exploitability.
Setup that does not lie to you
- Burp browser (or Chromium with the extension) via Burp’s proxy.
- Enable DOM Invader; start with default canary settings.
- Browse the app like a user — login, search, profile, deep links, OAuth return URLs.
- Open the DOM Invader tab when something looks interesting; note source → sink pairs.
- Revisit flows after soft navigations; client routers often re-parse the URL without a full reload.
Hash and postMessage flows need deliberate navigation. Click the weird buttons. Open # links from emails if you have test messages. Inject canaries into query params the UI copies into the client state store.
Reading the noise
Expect false friends:
- Debug sinks only in development builds
- jQuery-era sinks behind feature flags you cannot reach as a normal user
- Canary in
textContentpaths that never become HTML - Framework sanitizers that break the PoC even when a sink lights up
- Browser extensions that inject their own DOM noise while you test
Promote a finding only when you control the source (location, postMessage origin checks failing, URL param, stored value) and land script execution or a meaningful privileged action. If Invader shows a sink but your manual payload dies in a sanitizer, document the sink class and move on — or find a markup context the sanitizer misses (href, SVG, template literals).
From sink to PoC
- Identify the source (e.g.
location.hashslice after?). - Minimal payload that reaches the sink — often HTML injection before full JS.
- Escalate to cookie theft, session actions, or token exfil if CSP allows.
- Retest in a clean profile without Burp instrumentation when possible — some programs ask for a standalone HTML/URL PoC.
- Note frame ancestry; nested iframes change which origin’s DOM you touch.
If CSP blocks inline script, try gadget-friendly sinks (script src, framework template injection) or report DOM injection with clear impact limits. A forced redirect to an OAuth consent URL can still be High even without alert.
Where it pays on real apps
- Client-side routers that trust fragment paths
- Preview panes that assign
innerHTMLfrom API JSON postMessagelisteners withevent.originchecks missing or too broad- Third-party widgets that rewrite the DOM from query params
- Markdown/WYSIWYG previews that hydrate dangerously on the client
Document browser version, exact URL, and whether the bug needs a click. Pair Dom Invader screenshots with the final standalone exploit URL. Official docs: DOM Invader. Use them for toggles; use your two test accounts for impact.