1

OWASP mentions the following example of code vulnerable to a DOM based XSS attack:

Select your language:    
<select><script>    
document.write("<OPTION value=1>"+document.location.href.substring(document.location.href.indexOf("default=")+8)+"</OPTION>");    
document.write("<OPTION value=2>English</OPTION>");    
</script></select>

And they say it can be attacked with the following URL:

http://www.some.site/page.html?default=<script>alert(document.cookie)</script>

This makes me wounder if the web browser does JavaScript evaluation twice? I.e., does it run document.write's first and then turn the code into the output displayed below, and then run it again to execute the alert box script? How are the HTML and JavaScript parsers triggered - parallel/sequential/top down/bottom up? What's the order they follow?

Select your language:
<select>
<OPTION value=1><script>alert(document.cookie)</script></OPTION>
<OPTION value=2>English</OPTION>
</select>
1

First the browser hands over the incoming data to the HTML parser, that starts working from the top of the document and down. This can happend even before the document has finnished downloading. As soon as the HTML parser comes to a script tag, it hands over the content to the JavaScript engine that start executing the code right away.

If the script contains document.write, it will write content to the document stream that the HTML is reading from. So the content will end up right below the script tag that created it.

When the script engine is done, the HTML parser continues parsing the document after the script tag. There, the first thing it will find is the ouput from document.write that it will happily parse. If that ouput contains another script tag, it will run it just like any other.

So it's only one pass, top down, with the initative switching between the HTML parser and the JS engine. Or, to say it with an image... You know that scene from Wallace & Gromit where Gromit is sitting on top of a toy train, laying out the tracks in front of it as it speeds forward? Well, the train is the HTML parser, Gromit is the JS engine doing document.write, and the tracks is the document stream.

I'll admit that this is a bit of a simplification. For instance, the browser may continue parsing the HTML document while it runs the script in the hope that the script will not use document.write. And then there's the HTML5 async and defer as well.

  • "If that ouput contains another script tag, it will run it just like any other." -> totally answers my question! – user172171 May 11 '18 at 19:31

Your Answer

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