初探node.js相关之原型链污染
字数 1076 2025-08-29 08:31:35
Node.js原型链污染漏洞深入解析
一、Node.js基础概念
1. Node.js简介
- Node.js是基于Chrome V8引擎的JavaScript运行时环境
- 特点:事件驱动、非阻塞I/O模型
- 模块系统:通过
require引入第三方模块
2. 同步与异步操作
- 同步:阻塞式操作,顺序执行
var data = fs.readFileSync('file.txt'); - 异步:非阻塞式操作,通过回调函数处理结果
fs.readFile('file.txt', function(err, data) { ... });
3. 关键模块
fs模块(文件系统)
- 提供文件操作功能
- 同步/异步方法对应:
readFileSync/readFilewriteFileSync/writeFile
child_process模块(子进程)
- 创建子进程的方法:
- 异步:
spawn,exec,execFile,fork - 同步:
spawnSync,execSync,execFileSync
- 异步:
- 安全风险:可能导致命令执行漏洞
二、JavaScript原型链机制
1. 核心概念
-
prototype:函数特有属性,指向原型对象
function Food() { this.bar = 1; } Food.prototype.bar2 = 2; -
proto:对象属性,指向构造函数的原型对象
let food = new Food(); console.log(food.__proto__ === Food.prototype); // true
2. 原型链继承
- 查找机制:
- 查找对象自身属性
- 沿
__proto__向上查找原型链 - 直到
Object.prototype(终点为null)
function Parent() { this.parentProp = 1; }
function Child() { this.childProp = 2; }
Child.prototype = new Parent();
let obj = new Child();
console.log(obj.parentProp); // 通过原型链查找到
三、原型链污染漏洞原理
1. 基本概念
通过修改对象的原型属性,影响所有继承该原型的对象
2. 漏洞示例
let obj1 = { a: 1 };
obj1.__proto__.polluted = "污染值";
let obj2 = {};
console.log(obj2.polluted); // 输出"污染值"
3. 污染途径
- 通过
__proto__属性直接修改 - 通过不安全的对象合并/复制操作
四、实战案例分析
案例1:CTFSHOW Web334
- 漏洞点:大小写转换绕过
// 检查逻辑 name !== 'CTFSHOW' && item.username === name.toUpperCase() - 绕过方法:使用
ctfshow等非全大写形式登录
案例2:CTFSHOW Web335/336
- 漏洞点:
eval命令执行 - 绕过方法:
// 使用同步方法执行命令 require('child_process').execSync('ls') // 或使用spawnSync require('child_process').spawnSync('ls').stdout.toString()
案例3:CTFSHOW Web337
- 漏洞点:MD5比较绕过
- 利用数组特性绕过严格比较:
?a[]=1&b[]=2
案例4:CTFSHOW Web338(原型链污染)
- 漏洞代码:
utils.copy(user, req.body); if(secret.ctfshow === '36dboy') { ... } - 攻击Payload:
{ "__proto__": { "ctfshow": "36dboy" } }
五、防御措施
- 避免使用不安全的对象合并函数
- 冻结原型对象:
Object.freeze(Object.prototype); - 使用
Object.create(null)创建无原型对象 - 对用户输入进行严格过滤和验证
- 使用
hasOwnProperty检查对象自身属性
六、扩展学习
-
其他Node.js常见漏洞:
- 模板注入(SSTI)
- 不安全的模块导入
- 路径遍历
-
深入研究:
- V8引擎工作机制
- JavaScript原型继承模型
- Node.js事件循环机制
通过深入理解原型链机制和Node.js运行原理,可以更好地识别和防御此类安全漏洞。