4

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)

KajMagnus
  • 11,308
  • 15
  • 79
  • 127

2 Answers2

3

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 #

p0deje
  • 3,903
  • 1
  • 26
  • 37
  • 1
    Of course, an XSS vulnerability like that would be pretty easy to exploit even if you _don't_ allow links beginning with `#` in user content. If you're vulnerable to that attack, you should really fix the actual vulnerability. (There's a general security principle involved here: never pass unfiltered user input to [DWIM](http://catb.org/jargon/html/D/DWIM.html) functions like jQuery's `$(...)` or PHP's `fopen()`, etc.) – Ilmari Karonen Feb 03 '12 at 16:10
  • Interesting! (And I agree with @IlmariKaronen that the "correct" solution is to upgrade/patch jQuery) – KajMagnus Feb 03 '12 at 21:17
  • I just realized that your regex is wrong because I can post `http://yoursite.com#evil` and it will pass. So, anchors are anyway in game. – p0deje Feb 04 '12 at 07:50
3

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.

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153
  • "*an attacker could still include a malicious fragment identifier in a full URL*" -- that's a good point – KajMagnus Feb 05 '12 at 11:41