高级漏洞篇之原型污染专题
字数 1234 2025-08-10 16:34:39
JavaScript原型污染漏洞详解
1. 什么是原型污染?
原型污染是一种JavaScript漏洞,攻击者可以利用它向全局对象原型添加任意属性。这些属性可能会被用户定义的对象继承,从而控制原本无法访问的对象的属性。
关键特点:
- 通常无法作为独立漏洞利用
- 可与其他漏洞结合导致严重后果
- 客户端可能导致DOM XSS
- 服务器端可能导致远程代码执行
2. JavaScript原型与继承基础
2.1 JavaScript对象
JavaScript对象是一组键值对(属性)的集合:
const user = {
username: "natsuk0",
userId: 01234,
isAdmin: false
}
2.2 原型概念
每个JavaScript对象都链接到另一个对象,称为它的原型:
let myObject = {};
Object.getPrototypeOf(myObject); // Object.prototype
let myString = "";
Object.getPrototypeOf(myString); // String.prototype
2.3 原型链
对象不仅从直接原型继承属性,还从原型链中所有上层对象继承属性:
username -> String.prototype -> Object.prototype -> null
2.4 访问原型的特殊属性
__proto__是大多数浏览器使用的非标准属性,用于访问对象原型:
username.__proto__ // String.prototype
username['__proto__'] // 同上
3. 原型污染漏洞的产生
3.1 漏洞产生条件
当JavaScript函数递归合并包含用户可控属性的对象时,未对键进行清理,可能允许注入__proto__等特殊键。
3.2 污染机制
攻击者可以注入类似以下的结构:
targetObject.__proto__.evilProperty = 'payload';
3.3 关键组成部分
- 污染源(Source):用户可控的输入
- 接收器(Sink):执行任意代码的JavaScript函数或DOM元素
- 利用链:未经适当过滤传递到接收器的属性
4. 原型污染源(Source)
4.1 通过URL
https://vulnerable-website.com/?__proto__[evilProperty]=payload
4.2 通过JSON输入
{"__proto__": {"evilProperty": "payload"}}
4.3 通过Web消息
5. 原型污染接收器(Sink)
常见的接收器包括:
- 执行任意JavaScript的函数
- DOM元素(如innerHTML)
- 配置选项(如transport_url)
6. 利用链示例
6.1 典型利用场景
let transport_url = config.transport_url || defaults.transport_url;
let script = document.createElement('script');
script.src = `${transport_url}/example.js`;
document.body.appendChild(script);
6.2 攻击示例
https://vulnerable-website.com/?__proto__[transport_url]=data:,alert(1);//
7. 检测与利用方法
7.1 手动检测步骤
- 尝试注入任意属性:
vulnerable-website.com/?__proto__[test]=test - 检查是否成功污染:
Object.prototype.test // 应为"test" - 尝试不同表示法:
vulnerable-website.com/?__proto__.test=test
7.2 使用DOM Invader(Burp Suite工具)
- 在Burp内置浏览器中启用DOM Invader
- 自动扫描原型污染源和利用链
- 自动生成DOM XSS POC
8. 防御方法
8.1 基本防御
- 过滤用户输入中的
__proto__键
8.2 更安全的防御
- 使用无原型的对象:
Object.create(null) - 冻结原型:
Object.freeze(Object.prototype) - 使用Map代替普通对象
9. 高级技巧:替代污染向量
当__proto__被过滤时,可以使用构造函数属性:
myObject.constructor.prototype // 等同于myObject.__proto__
污染示例:
https://vulnerable-website.com/?constructor[prototype][evilProperty]=payload
10. 实际案例分析
案例1:通过transport_url的DOM XSS
- 污染原型:
/?__proto__[transport_url]=data:,alert(1); - 触发动态脚本加载
案例2:通过sequence属性的DOM XSS
- 污染原型:
/?__proto__.sequence=alert(1)- - 触发恶意代码执行
11. 总结
原型污染是一种强大的JavaScript漏洞,虽然通常需要与其他漏洞结合利用,但可能导致严重后果。防御关键在于:
- 正确处理用户输入
- 限制原型修改
- 使用更安全的数据结构
- 定期安全审计和测试
理解原型继承机制和污染原理对于开发安全的JavaScript应用至关重要。