XSS with $(location.hash)

demo

Click this link.

It works on IE, Firefox, Chrome, Opera. In Safari, location.hash is percent encoded, not work.

why?

$("#id") is css selector, $("<img>") is createElement, and $("#<img>") is createElement too.

how to fix

in your library

var hash = "#" + location.hash.replace(/[^\w]/g, "");
if ($(hash).size()) { ... }

or patch to jQuery

-       quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+       quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,

examples

thanks

@t_ashula