$(“#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
