Prototype Pollution扩展思考
字数 1183 2025-08-18 11:35:46

原型链污染(Prototype Pollution)扩展利用与防御研究

前言

原型链污染(Prototype Pollution)是一种JavaScript特有的安全漏洞,攻击者通过修改对象的原型属性,影响所有继承自该原型的对象,从而可能导致跨站脚本(XSS)等安全问题。本文深入探讨原型链污染的扩展利用方式,特别是如何利用它绕过HTML过滤器,以及如何通过流行的JavaScript库实现XSS攻击。

HTML过滤器绕过技术

过滤器工作原理

大多数HTML过滤器采用白名单机制,只允许特定的HTML标签和属性通过。过滤过程通常包括:

  1. 初始化过滤选项(设置白名单、回调函数等)
  2. 解析输入HTML
  3. 对比标签和属性与白名单
  4. 移除不在白名单中的内容

原型链污染攻击点

当存在原型链污染漏洞时,可以污染以下关键属性:

  • whiteList:修改允许的标签和属性
  • css:禁用CSS过滤
  • onTag:修改标签处理逻辑

具体攻击方法

攻击filterXSS类过滤器

// 污染whiteList添加危险属性
Object.prototype.whiteList = Object.prototype.whiteList || {};
Object.prototype.whiteList['img'] = ['src', 'onerror'];

// 或者直接关闭CSS过滤
Object.prototype.css = false;

攻击HtmlSanitizer

HtmlSanitizer使用以下白名单对象:

var tagWhitelist_ = { 'A': true, 'IMG': true, ... };
var attributeWhitelist_ = { 'src': true, 'href': true, ... };
var cssWhitelist_ = { 'color': true, ... };

攻击方式:

// 添加onerror属性到白名单
Object.prototype.attributeWhitelist_ = Object.prototype.attributeWhitelist_ || {};
Object.prototype.attributeWhitelist_['onerror'] = true;

防御措施

DOMPurify等现代过滤器已加入防御:

  1. 冻结(Freeze)配置对象防止修改
  2. 使用Object.create(null)创建无原型的白名单对象
  3. 检查关键配置属性是否被意外继承

从原型链污染到XSS的利用链

jQuery利用链

攻击流程

  1. 污染wrapMap对象添加恶意包装标签
  2. 当jQuery解析HTML时使用被污染的包装
  3. 触发XSS

攻击代码

// 污染wrapMap
Object.prototype.wrapMap = Object.prototype.wrapMap || {};
Object.prototype.wrapMap['malicious'] = [1, '', ''];

// 触发解析
$("<malicious>test</malicious>").appendTo("body");

关键代码分析

buildFragment函数中的关键部分:

tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2];

通过污染wrapMap控制wrap[1]wrap[2]的内容,插入恶意HTML。

Zepto利用链

攻击流程

  1. 污染对象添加事件处理器属性
  2. Zepto的fragment函数处理属性时触发

攻击代码

Object.prototype.onerror = "alert(1)";
$("", {}).appendTo("body");

关键代码分析

zepto.fragment函数中的属性处理:

$.each(properties, function(key, value) {
  if (methodAttributes.indexOf(key) > -1) nodes[key](value)
  else nodes.attr(key, value)
})

会自动遍历原型链上的属性并设置。

Sprint利用链

攻击流程

类似jQuery,通过污染wrapMap实现攻击。

攻击代码

Object.prototype.wrapMap = {
  malicious: {
    intro: '',
    outro: ''
  }
};

关键代码分析

createDOM函数中的HTML拼接:

tmp.insertAdjacentHTML("afterbegin", inMap.intro + validHTML + inMap.outro);

防御建议

  1. 使用Object.create(null)创建无原型的配置对象
  2. 冻结(Freeze)关键配置对象
  3. 对用户输入进行严格验证
  4. 使用现代HTML净化库并保持更新
  5. 避免不安全的对象合并操作

参考资源

  1. Client-Side Prototype Pollution
  2. Prototype Pollution and Bypassing Client-Side HTML Sanitizers
  3. DOMPurify防御措施

通过深入理解原型链污染的原理和利用方式,开发者可以更好地防御这类安全威胁,构建更安全的Web应用。

原型链污染(Prototype Pollution)扩展利用与防御研究 前言 原型链污染(Prototype Pollution)是一种JavaScript特有的安全漏洞,攻击者通过修改对象的原型属性,影响所有继承自该原型的对象,从而可能导致跨站脚本(XSS)等安全问题。本文深入探讨原型链污染的扩展利用方式,特别是如何利用它绕过HTML过滤器,以及如何通过流行的JavaScript库实现XSS攻击。 HTML过滤器绕过技术 过滤器工作原理 大多数HTML过滤器采用白名单机制,只允许特定的HTML标签和属性通过。过滤过程通常包括: 初始化过滤选项(设置白名单、回调函数等) 解析输入HTML 对比标签和属性与白名单 移除不在白名单中的内容 原型链污染攻击点 当存在原型链污染漏洞时,可以污染以下关键属性: whiteList :修改允许的标签和属性 css :禁用CSS过滤 onTag :修改标签处理逻辑 具体攻击方法 攻击filterXSS类过滤器 攻击HtmlSanitizer HtmlSanitizer使用以下白名单对象: 攻击方式: 防御措施 DOMPurify等现代过滤器已加入防御: 冻结(Freeze)配置对象防止修改 使用 Object.create(null) 创建无原型的白名单对象 检查关键配置属性是否被意外继承 从原型链污染到XSS的利用链 jQuery利用链 攻击流程 污染 wrapMap 对象添加恶意包装标签 当jQuery解析HTML时使用被污染的包装 触发XSS 攻击代码 关键代码分析 buildFragment 函数中的关键部分: 通过污染 wrapMap 控制 wrap[1] 和 wrap[2] 的内容,插入恶意HTML。 Zepto利用链 攻击流程 污染对象添加事件处理器属性 Zepto的 fragment 函数处理属性时触发 攻击代码 关键代码分析 zepto.fragment 函数中的属性处理: 会自动遍历原型链上的属性并设置。 Sprint利用链 攻击流程 类似jQuery,通过污染 wrapMap 实现攻击。 攻击代码 关键代码分析 createDOM 函数中的HTML拼接: 防御建议 使用 Object.create(null) 创建无原型的配置对象 冻结(Freeze)关键配置对象 对用户输入进行严格验证 使用现代HTML净化库并保持更新 避免不安全的对象合并操作 参考资源 Client-Side Prototype Pollution Prototype Pollution and Bypassing Client-Side HTML Sanitizers DOMPurify防御措施 通过深入理解原型链污染的原理和利用方式,开发者可以更好地防御这类安全威胁,构建更安全的Web应用。