Se vedi come il tuo codice viene effettivamente consegnato dal server (ad esempio utilizzando il menu di scelta rapida "Visualizza frame frame" in Chrome per la cornice bianca in jsfiddle) puoi vedere che è incorporato in qualche altro codice come questo :
<body>
<svg/onload=alert(1)
<script>
Questo significa essenzialmente che l'intero elemento HTML visto dal browser inizia con <svg
e termina con >
. <
non sarà considerato come l'inizio di un nuovo elemento HTML poiché l'elemento esistente non è stato ancora chiuso.
<svg/onload=alert(1) <script>
Dopo aver aggiustato il browser probabilmente interpreterà questo come <svg onload=A B>
dove A è alert(1)
e B è <script
, quindi eseguendo il tuo carico utile A e ignorando l'attributo B poiché non viene definito alcun comportamento per esso.
Per i dettagli su come viene eseguito l'analisi, consulta la definizione della sintassi HTML5 che descrive il parser in dettaglio. Seguendo lo standard finirai con:
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 altre parole come ho detto prima: il tag è svg
, l'attributo onload
ha un valore di attributo di alert(1)
e c'è un altro attributo <script
.