Is it safe to allow links that start with # (hash)?

1.2k Views Asked by At

I'm building a webapp and users can create HTML contents dynamically. Is it safe (e.g. w.r.t. XSS attacks) to allow them to create links that start with #?

I don't know why it wouldn't be -- perhaps I'm just being paranoid. (My Javascript code doesn't do anything particular, for # URLs.)

Anyway one reason I ask is that I'm using Google Caja's html-sanitizer to sanitize HTML. It filters URL:s, however the default filter looks like so:

function urlX(url) { if(/^https?:\/\//.test(url)) { return url }}

That is, the protocol must be specified and only HTTP and HTTPS are allowed but not javascript:. I recently changed the URL filtering function to:

function urlX(url) {
  if (/^https?:\/\//.test(url) || /^#/.test(url)) return url;
}

(That is, #.... is allowed as well.)

I thought that perhaps I should ask if you think #... links are safe?

(For example, the browser won't do anything insane with links like `href='#javascript:....'? Well it does not (not my browser anyway), but perhaps there is some other ...something... that I'm not aware about)

2

There are 2 best solutions below

1
On BEST ANSWER

It should be safe: anything after a # in a URL is parsed as a fragment identifier by browsers.

Of course, if you have some JavaScript on the page that reads that fragment identifier and does something unsafe with it, then all bets are off. But note that, in such a case, you have a more fundamental security problem that you need to fix.

Just disallowing links than begin with # won't do much, since an attacker could still include a malicious fragment identifier in a full URL, or even in a link pointing to your site from somewhere else.

3
On

It's not safe. For example, there was an XSS issue with jQuery's $(location.hash). There is PoC at http://ma.la/jquery_xss/.

So either forbid this or properly sanitize everything after #