28

I am trying to understand how DOM based XSS work, e.g. from this post, I managed to reproduce it in IE11, but e.g. Chrome and Firefox are immune at least against this exact example.

What happens is that document.baseURI and similar objects do return a string that is encoded, so unless you explicitly write code to decode it back or something I don't see how it can be abused.

Are there any other examples that the modern browsers are still vulnerable to? I did not manage to find any, since virtually all examples on web point to a similar vulnerability.

P.S. The gist of the example is to form a hashbang query with injection:

http://victim/displayHelp.php?title=FAQ#<script>alert('Hello')</script>
51

Yes, DOM-based XSS is still a concern. While some issues cannot be exploited due to URL encoding, there a number of situations where URL encoding will not stand in the way of exploitation.

The gist of the example is to form a hashbang query with injection

That's one example, but DOM-based XSS encompasses all XSS issues that result from insecurely handling data via JavaScript.

Data can come from sources such as the URL, the DOM itself, etc.

The most basic example where user input is eg read from location.search and processed with innerHTML or .write will indeed not work with any up-to-date browser, as the value is URL-encoded.

But DOM-based XSS with different sources than location.search or different sinks than innerHTML will still work, and do exist in real-world applications.

An incomplete list of examples with different sinks and sources can be found below.

Source: URL

An example for a DOM-based XSS vulnerability where the user input comes from the URL:

<html>
<body>
<script>
    url = new URLSearchParams(location.search);
    x = url.get('x');
    document.write(x);
</script>
</body>
</html>

Attack:

http://example.com/test.html?x=<script>alert(1)</script>

Source: The DOM

In my experience, this is the most common class of exploitable DOM-based XSS issues.

Let's assume an application that properly HTML-encodes all user-supplied data that is inserted into the HTML code.

Applications will still often read out user-supplied data from the DOM, and then reinsert it in an insecure manner. For example:

<html>
<body>
<input type="text" id="userinput" value="&quot;><img src=x onerror=alert(1)>">
<div id="output"></div>
<script>
    userinput = document.getElementById('userinput').value;
    output = document.getElementById('output');
    output.innerHTML = "Your input was: " + userinput;
</script>
</body>
</html>

Sink: Eval

Sometimes, we don't need " or > to gain XSS. An example would be user input that is passed to eval:

<html>
<body>
<script>
    x = window.location.hash.substr(1);
    eval("var myvar = '" + x + "'");
</script>
</body>
</html>

Attack:

http://example.com/test.html#';alert(1);x='

Sink: document.write

Another example where we do not need " or > and which works with document.write:

<html>
<body>
<script>
    x = window.location.hash.substr(1);
    document.write("<input type='text' value='" + x + "'");
</script>
</body>
</html>
</body>
</html>

Attack:

http://example.com/test.html#test'onmouseover='alert(1)
  • Thanks a lot for a very good and comprehensive answer! – Ilya Chernomordik Oct 21 at 8:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.