Perché questo vettore:
<svg><script>alert(/1/.source)</script>
funziona in link e questo
<script>alert(/1/.source)</script>
non lo fa. In che modo <svg>
lo fa funzionare?
HTML <script>
ha poteri speciali che altri elementi non hanno: è un "elemento CDATA". Ciò significa che qualsiasi carattere <
o &
fino alla fine dell'elemento viene preso come significato letterale di quei caratteri. Quindi, ciò che viene passato all'interprete JS è:
alert(/1/.source)
che ovviamente non è una sintassi JS valida.
Il concetto di un "elemento CDATA" deriva dal mondo SGML da cui è sviluppato HTML. Ma SVG viene dal mondo XML in cui le cose sono semplificate e non ci sono elementi CDATA. Di conseguenza l'elemento SVG <script>
non ha poteri speciali: all'interno di uno script SVG, <
introduce un tag e &
introduce un riferimento a entità o carattere.
Di conseguenza (
viene analizzato in (
e la stringa risultante passata all'interprete JS è:
alert(/1/.source)
Nei termini XML l'elemento <script>
si trova nello spazio dei nomi HTML e l'elemento <svg><script>
si trova nello spazio dei nomi SVG, quindi sono elementi diversi. HTML5 rende tutto ciò meno chiaro nascondendo i prefissi dello spazio dei nomi e applicando un parser non XML all'SVG (che è il motivo per cui (
funziona nonostante non sia ben formato, dovrebbe essere (
).
Il #
(hash, sharp, pound) interrompe il tuo Javascript. All'interno di una coppia di tag <svg>
(il tag di chiusura non viene fornito) il numero dell'entità viene convertito nel riferimento di carattere appropriato quando viene visualizzato come html, quindi il motore esegue Script ECMA (che è permesso fare per disegnare) .
OWASP.org lo documenta come codifica esadecimale senza punto e virgola .