No , en los navegadores modernos no es posible XSS a través del atributo style o src de una etiqueta <img> .
Por lo tanto, ninguno de estos ejecutaría el código JS en ningún navegador actualizado:
<img src="javascript:alert(1)">
<img src="x.jpg" style=background-image:url('javascript:alert(2)')">
El soporte para Javascript en los atributos CSS tiene Ha sido abandonado hace mucho tiempo . Puede encontrar algunas referencias anteriores al respecto aquí .
Análisis de su código de ejemplo
location.hash siempre comienza con un símbolo # . Dado que este carácter es ilegal en JS y no es un inicio válido de una nueva URL, ningún XSS sería posible en primer lugar. (Por ejemplo, eval(location.hash) siempre produce un error de sintaxis).
Supongamos que ignora que # y location.hash realmente podrían contener cualquier cadena que desee.
Entonces este control de seguridad es defectuoso:
(location.hash.indexOf('javascript:') !== 0)
Un atacante aún podría construir una URL que comience con JaVaScRiPt: . Además, es arriesgado suponer que ninguna implementación permitiría nunca espacios iniciales o caracteres de control (por ejemplo, \t\x00javascript: ). ¿Y qué pasa con la codificación de URL? Una carga útil que comienza con javascript%3a pasaría su filtro. Además, ¿quieres permitir el protocolo data: ? Si desea restringir la URL a ubicaciones absolutas, puede agregar a la lista blanca los inicios http:// y https:// en lugar de poner en la lista negra javascript: .
Esto está bien:
img.src='some/local/path/'+location.hash;
Incluso si el atributo src era susceptible al código de script, su prefijo some/local/path/ garantiza que no se pueda convertir en una URL de JS. Sin embargo, un atacante podría especificar cualquier ruta relativa a un archivo de imagen en el mismo servidor, lo que podría encontrar indeseable.
NB: se trata de construir URL javascript: maliciosas. Si desea utilizar valores controlados por el usuario como location.hash para la salida HTML o un contexto diferente, debe desinfectar la cadena correctamente.