3

My static code analyser flags this piece of Javascript on my client's web site as a potential DOM based XSS:

var x = $('#' + window.location.hash.substr(1))
x.addClass('highlighted').find('div').show();

The code is directly in $(function(){ ... } so should be run every time the page loads? (confession: I know too little about jQuery...)

Googling, I found that jQuery made exploiting code like this more difficult after this article from 2011:

http://blog.mindedsecurity.com/2011/07/jquery-is-sink.html

But attacks are still possible, one that stills works is at http://www.mjcblog.net/2011/06/jquery-selector-injection/ .

Is my client still vulnerable? I think so, but I can't come up with an exploit because I don't know jQuery well enough to really get what's going on.

Edit - since the value passed to $() always starts with # I suspect that this blocks any exploit of this, and trying it on the Firefox and Chrome console seems to confirm this - but I'm still not sure there isn't another way :)

Mark Koek
  • 1,311
  • 1
  • 8
  • 16
  • Could you actually try this vector on the jQuery version your client it running and see if it works? IIRC, jQuery stopped parsing tags mixed with plain-text a long time ago. – billc.cn Apr 19 '16 at 11:02
  • Good idea. They're running jQuery 1.8.3 and the PoC works when I use that instead of the 1.6.3 that's in the PoC. – Mark Koek Apr 19 '16 at 11:13
  • I just want to confirm: the exploit should not work under 1.8.3. – billc.cn Apr 19 '16 at 12:22
  • It does (note that it is the second one where the author says: this is still going to work despite the fix introduced in jQuery 1.6.3). I have stored the PoC locally and only changed the script import to 1.8.3 as hosted by my client. It works under Chromium, I get the alert box saying 'xss'. – Mark Koek Apr 19 '16 at 12:54
  • To clarify: there's no 'exploit' in the second post. It is how it is supposed to work. If you use an HTML tag as the argument of `jQuery`, the element will be created. The bug fix addresses arguments that starts with the `#` character which is the case in the code you've given. – billc.cn Apr 19 '16 at 19:48
  • Right. I tried some things on the console and saw that I can do `.classname,` and it will be created but not `#idname,` - that gives an error. So the hardcoding of the `#` in the argument to `$()` safeguards them from this issue. – Mark Koek Apr 20 '16 at 13:40

1 Answers1

4

Whether or not the client is vulnerable depends on the version of jQuery and on whether or not they are also loading jQuery migrate. I built this test site a while back, where I test different versions of jQuery against two of these bugs: http://research.insecurelabs.org/jquery/test/

Retire.js (free open source tool maintained by me) will tell you if the versions of jQuery you have on that site are vulnerable or not: http://retirejs.github.io/retire.js/ The chrome version of Retire.js may be you preferred choice.

Erlend
  • 2,195
  • 14
  • 13
  • Can't test now but they are running 1.8.3. – Mark Koek Apr 20 '16 at 13:38
  • So not vulnerable, bug 11290 is something else, we're talking bug 9521. OK, thanks. – Mark Koek Apr 20 '16 at 13:54
  • 1
    Bug 11290 appears to affect more than just selectors of elements with a requested attribute. The following selectors seem vulnerable in 1.8.3 in addition to `TAG[ATTR=']`: `.CLASS` and `TAG `. – eel ghEEz Jun 14 '18 at 15:01