CodePark/ questions / XSS: sources, sinks & sanitizing
START PRACTICINGPRACTICE
Frontend question · Frontend security › XSS: sources, sinks & sanitizing

In DOM-based XSS, what are sources and sinks? Name the common ones.

// https://app.example/welcome#<img src=x onerror=alert(document.cookie)>
const name = decodeURIComponent(location.hash.slice(1));
document.getElementById("greet").innerHTML = "Hi " + name;

DOM-based XSS happens fully inside the browser. Your own JavaScript reads data the attacker controls (the source) and passes it to an API that turns a string into HTML or code (the sink). In the example, location.hash is the source and innerHTML is the sink. The part after # is never sent to the server, so server-side filters never see the payload.

Common sources:

  • location.href, location.search and location.hash
  • document.referrer and window.name
  • postMessage data from other windows
  • data from your API that another user wrote, such as a comment

Common sinks:

  • HTML sinks: innerHTML, outerHTML, insertAdjacentHTML, document.write, and jQuery's .html()
  • Code sinks: eval, new Function, and setTimeout or setInterval called with a string
  • URL sinks: a.href, iframe.src and location.href, which run a javascript: URL

Fixes:

  • Use safe APIs: textContent instead of innerHTML, and createElement plus setAttribute instead of building HTML strings.
  • Check that URLs start with https: or http: before you use them.
  • When you really need HTML, sanitize it with a library like DOMPurify.
  • Turn on Trusted Types, so the browser rejects plain strings at the dangerous sinks.
  • A source is where attacker-controlled data enters, such as location.hash or postMessage data.
  • A sink is an API that turns a string into HTML, code or a navigation, such as innerHTML or eval.
  • DOM-based XSS can happen without the payload ever reaching the server.
  • URL sinks like href can run javascript: URLs.
  • The fix is safe APIs like textContent, URL scheme checks and sanitizing when HTML is needed.