前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >jQuery最新xss漏洞分析——CVE-2020-11022/11023

jQuery最新xss漏洞分析——CVE-2020-11022/11023

作者头像
Jayway
发布2020-06-03 15:56:06
31.3K0
发布2020-06-03 15:56:06
举报
文章被收录于专栏:卓文见识

一、背景

jQuery官方上周发布了最新版本3.5.0,主要修复了两个安全问题,官方博客为:

代码语言:javascript
复制
https://blog.jquery.com/2020/04/10/jquery-3-5-0-released/

据NVD描述:在大于或等于1.2且在3.5.0之前的jQuery版本中,即使执行了消毒(sanitize)处理,也仍会执行将来自不受信任来源的HTML传递给jQuery的DOM操作方法(即html()、.append()等),从而导致xss漏洞。

二、前置知识

在讲解漏洞之前,需要了解jQuery的基本用法和历史漏洞,具体可参考:jQuery框架漏洞全总结及开发建议:

代码语言:javascript
复制
https://mp.weixin.qq.com/s/M1BYj6VbeoNV4C5M7cR_hA

而与此次jQuery漏洞联系比较紧密的是html()等方法,此方法返回或设置被选元素的内容 (inner HTML),可用于设置所有选定元素的内容,看一个简单的使用案例:

此处定义一个点击事件,会对所有的p元素进行匹配,并修改为相同的内容。

三、漏洞复现

对于此漏洞原作者搭建了在线环境,内置了三个xss poc,点击Append via .html()按钮即可触发xss:

代码语言:javascript
复制
https://vulnerabledoma.in/jquery_htmlPrefilter_xss.html

审查源码,逻辑很简单:

首先使用如下代码模拟了一个开发场景,即将页面的所有div元素替换为根据ID取到的sanitizedHTML:

代码语言:javascript
复制
<script>
function test(n,jq){
   sanitizedHTML = document.getElementById('poc'+n).innerHTML;
   if(jq){
       $('#div').html(sanitizedHTML);
   }else{
       div.innerHTML=sanitizedHTML;
    }
}
</script>

虽然三个poc都使用了包含onerror事件的img标签,但其实它们是放在属性或style元素内部,因此会绕过HTML清理器。

以poc1为例,根据此id取到的值如下:

代码语言:javascript
复制
<style><style /><img src=xonerror=alert(1)>

点击之后,执行xss,此时审查div元素:

发现我们提交的poc多了一个闭合标签</style>,变成了:

代码语言:javascript
复制
<style><style /></style><imgsrc=x onerror=alert(1)>

</style>闭合了<style>标签,成功执行后面的<img>脚本,导致xss。

四、漏洞原理

1、CVE-2020-11022

导致上述问题的关键是,在html()方法中,作为参数传递的HTML字符串将传递到 $ .htmlPrefilter()方法:

代码语言:javascript
复制
https://api.jquery.com/jQuery.htmlPrefilter/

这个方法用于替换自闭合标签,如将<tagname /> 替换为 <tagname ></tagname>,3.x版本之前使用的正则为:

代码语言:javascript
复制
rxhtmlTag =/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi
[...]
htmlPrefilter: function( html ) {
  return html.replace(rxhtmlTag, "<$1></$2>" );
}

3.x之后使用的正则为:

代码语言:javascript
复制
rxhtmlTag =/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi

这就使用到环境里的poc2(仅适用于jQuery3.x),注意这里的xss payload是作为属性出现,所以可以绕过消毒器规则

代码语言:javascript
复制
<img alt="<x" title="/><img src=xonerror=alert(1)>

该poc使用html()方法执行后发现变为:

代码语言:javascript
复制
<img alt="<x" title="/></x”><imgsrc=x onerror=alert(1)>

该正则会将x"识别为标签并新增</x”>闭合标签,从而达到xss的效果:

2、CVE-2020-11023

针对上述漏洞原理,jQuery Team进行了修复,修复手段为将$.htmlPrefilter()方法替换为标识函数,因此传递的HTML字符串现在不再经过htmlPrefilter函数处理,从而成功修复了漏洞。但仍有一些手段可以绕过,CVE-2020-11023就是针对CVE-2020-11022的绕过:

绕过使用的是另一个特性,某些特殊的标签在经过html()方法处理时,会由于HTML的特性或浏览器的bug而使得这些标签被移除。

option就是这些特殊标签之一,我们知道option 元素通过位于 select 元素内部来构造一个选择列表,但如果没有select元素,option会被移除。为了解决这个bug,如果传入参数的第一个元素为option,jQuery会新增<select multiple='multiple’>和</select>。

所以我们提交poc3:

代码语言:javascript
复制
<option><style></option></select><imgsrc=x onerror=alert(123456)></style>

经过处理会变为:

代码语言:javascript
复制
<select multiple='multiple'><option><style></option></select><imgsrc=x onerror=alert(123456)></style></select>

根据HTML从前往后解析的顺序,会先解析一个<select>标签,且<select>不允许将大部分HTML标签包裹其中,导致<style>被忽略,而后识别<img>标签从而xss。

此漏洞在最新的3.5.0中也被修复,对于特殊的标签进行了处理。

代码语言:javascript
复制
https://github.com/jquery/jquery/commit/966a70909019aa09632c87c0002c522fa4a1e30e#diff-51ec14165275b403bb33f28ce761cdedR25

五、总结

1、漏洞利用

1)系统使用jQuery的html()、append()或$('<tag>')等方法处理用户输入;

2)用户输入已经过“消毒”(sanitize)处理。

2、修复方案

1)更新jQuery到3.5.0或更高版本

代码语言:javascript
复制
https://code.jquery.com/jquery-3.5.0.js

2)使用XSS清理工具清理用户输入的HTML,官方推荐:

代码语言:javascript
复制
https://github.com/cure53/DOMPurify
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 卓文见识 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二、前置知识
  • 三、漏洞复现
  • 四、漏洞原理
    • 1、CVE-2020-11022
      • 2、CVE-2020-11023
      • 五、总结
        • 1、漏洞利用
          • 2、修复方案
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档