SPOILER ALERT : Do not continue if you do not want to be spoiled

I am currently doing the Google XSS Challenge Level 2 .

I am injecting XSS code that is inserted into the document using element.innerHTML. I don't understand why <script>alert("Foobar")</script> does not work but <img src="/" onerror = "alert(1);" works.

I have tried looking at source code but I still don't understand why. I am new to XSS, hence I would appreciate if you would make reference to the source code when formulating your answers.


The answer to that depends on the way the browser executes scripts present in different places within a page. For example:

  • JavaScript within the inline script tags is processed synchronously with the other markups in the webpage. These script tags might slow down the processing of a web page.
  • Script tags which are assigned to the elements after the DOM loads (as in the case of challenge 2) are actually never executed in most cases (see Exception at the end of the answer)!
  • JavaScript inside an event handler as an attribute is executed as soon as a particular event occurs (reason why inputs like <img src="/" onerror = "alert(1);" and <body onload="alert(2)"></body> will work in this case).


Script tags with a defer attribute will not be executed (on some browsers) until the DOM has been fully rendered. For instance, I tried the same challenge on IE and I was able to alert a popup using the following user input:

<script defer>alert(2)</script>

Scripts injected into the DOM via script tags in innerHTML are not run at the time they are injected (inline scripts are run at the time the original page is parsed). On the other hand, images injected into the DOM are loaded at that time, and if the loading fails, then the onerror event handler is called.

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.