No, in modern browsers no XSS is possible via the style or src attribute of an <img> tag.
So neither of these would execute the JS code in any up-to-date browser:
<img src="javascript:alert(1)">
<img src="x.jpg" style=background-image:url('javascript:alert(2)')">
Support for Javascript in CSS attributes has long been abandoned. You can find some older references about it here.
Analysis of your example code
location.hash always starts with a # symbol. Since this character is illegal in JS and not a valid beginnig of a new URL, no XSS would be possible in the first place. (For instance, eval(location.hash) always produces a syntax error.)
Let's assume, you ignore the # and location.hash could really contain any string you want.
Then this security check is flawed:
(location.hash.indexOf('javascript:') !== 0)
An attacker could still construct a URL starting with JaVaScRiPt:. Also, it's risky to assume that no implementation would ever allow leading spaces or control characters (e.g. \t\x00javascript:). And what about URL-encoding? A payload starting with javascript%3a would pass your filter. Also, do you want to allow the data: protocol? If you like to restrict the URL to absolute locations, you could whitelist the beginnings http:// and https:// instead of blacklisting javascript:.
This is fine:
img.src='some/local/path/'+location.hash;
Even if the src attribute was susceptible to script code, your prefix some/local/path/ ensures that it cannot be turned into a JS URL. However, an attacker could specify any relative path to an image file on the same server, which you might find undesirable.
NB: This is about constructing malicious javascript: URLs. If you want to use user-controlled values like location.hash for HTML output or a different context, you have to properly sanitize the string.
location.hash.indexOf('ANY_STRING')would return0sincelocation.hashcontains#, so any string in the URL hash value would be at least on index1. The only exception is of courselocation.hash.indexOf(''). So before discussing any XSS vuln, the check in your code already fails. – Adi Jun 01 '16 at 21:10http://. That could be abused to scare away customers - they click on a link to your site, and are greeted with something offensive. – Anders Jun 01 '16 at 21:24