¿Por qué este vector:
<svg><script>alert(/1/.source)</script>
funciona en enlace y este
<script>alert(/1/.source)</script>
no lo hace. ¿Cómo hace <svg> para que funcione?
HTML <script> tiene poderes especiales que otros elementos no tienen: es un "elemento CDATA". Eso significa que cualquier carácter de < o & hasta el final del elemento se considera que significa literalmente esos caracteres. Entonces, lo que se pasa al intérprete de JS es:
alert(/1/.source)
que obviamente no es una sintaxis JS válida.
El concepto de "elemento CDATA" proviene del mundo SGML a partir del cual se desarrolló HTML. Pero SVG proviene del mundo XML donde las cosas se simplifican y no hay elementos CDATA. En consecuencia, el elemento SVG <script> no tiene poderes especiales: dentro de un script SVG, < introduce una etiqueta y & introduce una entidad o referencia de carácter.
En consecuencia, ( se analiza a ( y la cadena resultante que se pasa al intérprete de JS es:
alert(/1/.source)
En términos XML, el elemento <script> está en el espacio de nombres HTML y el elemento <svg><script> está en el espacio de nombres SVG, por lo que son elementos diferentes. HTML5 hace que todo esto sea menos claro al ocultar los prefijos de espacio de nombres y al aplicar un analizador no XML al SVG (por eso ( funciona a pesar de que no está bien formado; debería ser ( ).
El # (hash, sharp, pound) rompe tu Javascript. Dentro de un par de etiquetas <svg> (no se proporciona su etiqueta de cierre), el número de la entidad se traduce a su referencia de caracteres adecuada, ya que se procesa como html, luego el motor ejecuta el script ECMA (que está permitido hacer para dibujar) .
OWASP.org documenta esto como codificación hexadecimal sin punto y coma .