4

The following XSS injections will execute without the accompanying closing tag (see this demo):

<body/onload=alert(1)
<svg/onload=alert(1)
<iframe/onload=alert(1)

I just need to know why these work, any documentation link would also be appreciated.

Anders
  • 64,406
  • 24
  • 178
  • 215
Y M
  • 143
  • 5

1 Answers1

5

If you view how your code is actually delivered by the server (for example by using the "view frame source" context menu in Chrome for the white frame in jsfiddle) you can see that it is embedded in some other code like this:

<body>
  <svg/onload=alert(1)

  <script>

This essentially means that the full HTML element seen by the browser is starting with <svg and ending with >. The < will be not considered as the beginning of a new HTML element since the existing element is not yet closed.

<svg/onload=alert(1) <script>

After fixing up the browser will likely interpret this as <svg onload=A B> where A is alert(1) and B is <script, thereby executing your payload A and ignoring the attribute B since no behavior is defined for it.

As for the details how the parsing is done see the HTML5 syntax definition which describes the parser in detail. By following the standard you will end up with:

initial:    "data state" (8.2.4.1)
'<svg':     move to "tag open state" (8.2.4.6) and then "tag name state" (8.2.4.8)
'/':        move to "self closing state" (8.2.4.40)
'onload':   parse error, go do "before attribute name state" (8.2.4.32) and 
            from there to "attribute name state" (8.2.4.33) and read the attribute
'=':        switch to "attribute value state" (8.2.4.35)
'alert(1)': read attribute within "attribute value (unquoted) state" (8.2.4.38)
' ':        switch to "before attribute name state" (8.2.4.32)
'<script':  read attribute name within "attribute name state" (8.2.4.33)
'>':        switch to "after attribute name state" (8.2.4.34) and from there
            to "data state" (8.2.4.1)

In other words as I said shorter before: The tag is svg, the attribute onload has an attribute value of alert(1) and there is another attribute <script.

Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424