No , nei browser moderni non è possibile XSS tramite l'attributo style o src di un tag <img> .
Quindi nessuno di questi eseguirà il codice JS in qualsiasi browser aggiornato:
<img src="javascript:alert(1)">
<img src="x.jpg" style=background-image:url('javascript:alert(2)')">
Il supporto per Javascript negli attributi CSS ha a lungo abbandonato . Puoi trovare alcuni vecchi riferimenti a riguardo qui .
Analisi del tuo codice di esempio
location.hash inizia sempre con un simbolo # . Poiché questo carattere è illegale in JS e non è un inizio valido di un nuovo URL, non sarebbe possibile alcun XSS in primo luogo. (Ad esempio, eval(location.hash) produce sempre un errore di sintassi.)
Supponiamo che tu ignori # e location.hash possa davvero contenere qualsiasi stringa tu voglia.
Quindi questo controllo di sicurezza è difettoso:
(location.hash.indexOf('javascript:') !== 0)
Un utente malintenzionato potrebbe ancora costruire un URL che inizia con JaVaScRiPt: . Inoltre, è rischioso presumere che nessuna implementazione possa mai consentire spazi iniziali o caratteri di controllo (ad esempio \t\x00javascript: ). E la codifica dell'URL? Un payload che inizia con javascript%3a passerebbe il tuo filtro. Inoltre, vuoi consentire il protocollo data: ? Se desideri limitare l'URL alle posizioni assolute, puoi autorizzare gli inizi http:// e https:// invece di mettere in black list javascript: .
Questo va bene:
img.src='some/local/path/'+location.hash;
Anche se l'attributo src era suscettibile al codice di script, il prefisso some/local/path/ garantisce che non possa essere trasformato in un URL JS. Tuttavia, un utente malintenzionato potrebbe specificare qualsiasi percorso relativo a un file immagine sullo stesso server, che potrebbe risultare indesiderato.
NB: Si tratta della costruzione di URL javascript: dannosi. Se desideri utilizzare valori controllati dall'utente come location.hash per l'output HTML o un contesto diverso, devi disinfettare correttamente la stringa.