nodejs 原型链污染新视角
字数 1435 2025-09-23 19:27:46
Node.js 原型链污染新视角
原型链污染基础概念
原型链污染是Node.js中一种常见的安全漏洞,其基本原理如下:
-
原型链机制:
- 对象的
__proto__是原型,原型也是一个对象,也有__proto__属性 - 原型的
__proto__又是原型的原型,这样一直向上查找直到找到Object的原型 - 当在一个对象中寻找属性时,如果对象没有该属性,就会沿着原型链向上查找
- 对象的
-
污染原理:
- 通过直接污染
Object对象的属性值,使得目标对象在查找该属性时返回被污染的值 - 示例代码:
const foo = { bar: 1 }; foo.__proto__.bar = 2; console.log(foo.bar); // 1 (foo本身有bar属性) const zoo = {}; console.log(zoo.bar); // 2 (zoo没有bar属性,从原型链找到被污染的bar)
- 通过直接污染
原型链访问方式
通常有三种方式可以访问对象的原型:
objectname["__proto__"]objectname.__proto__objectname.constructor.prototype
实际案例分析
案例背景
分析一个基于Express的Node.js应用,主要功能包括:
- 用户注册(
/register) - 用户登录(
/login) - 主题配置(
/theme)
关键代码分析
-
用户注册逻辑:
app.post('/register', (req, res) => { const { username, password } = req.body; users[username] = { password: password, isAdmin: false, // 默认设置为false themeConfig: { /* 主题配置 */ } }; }); -
用户登录逻辑:
app.post('/login', (req, res) => { const { username, password } = req.body; const user = users[username]; // 关键点:会查找原型链 if (user && user.password === password) { req.session.userId = username; res.redirect('/'); } }); -
主题配置逻辑:
app.get('/theme', (req, res) => { // 将用户提交的参数合并到themeConfig中 // 存在原型链污染风险点 });
安全限制
应用中存在WAF过滤,阻止了以下关键词:
__proto__prototypeconstructor
创新攻击思路
传统思路的限制
传统原型链污染需要访问Object原型,但这里无法通过常规方式(__proto__等)访问原型。
新思路:利用Object已有属性
-
绕过登录验证:
- 使用
Object已有的方法名作为用户名(如isPrototypeOf) - 由于
users[username]会查找原型链,Object.isPrototypeOf存在 - 不提供密码,使
user.password === undefined === password
- 使用
-
新型污染方式:
- 无法直接污染
Object.prototype.isAdmin - 改为污染
Object.prototype.isPrototypeOf.isAdmin - 通过主题配置接口传入
isPrototypeOf.isAdmin=true
- 无法直接污染
-
条件满足逻辑:
users[req.session.userId].isAdmin=>users["isPrototypeOf"].isAdminusers对象没有isPrototypeOf属性,查找原型链- 找到被污染的
Object.isPrototypeOf.isAdmin=true
攻击步骤
- 访问
/theme路由,传入参数isPrototypeOf.isAdmin=1进行污染 - 使用用户名
isPrototypeOf和空密码登录 - 访问
/flag路由获取flag
防御建议
- 避免使用用户输入直接修改对象属性
- 使用
Object.create(null)创建无原型的对象 - 对用户输入进行严格过滤
- 使用
Object.hasOwnProperty检查属性是否存在 - 避免使用不安全的对象合并操作
总结
本案例展示了一种新型的原型链污染利用方式:
- 当无法直接访问
Object原型时,可以利用Object已有的属性进行间接污染 - 通过污染
Object已有属性的子属性,实现类似原型链污染的效果 - 结合JavaScript原型链查找机制,实现权限绕过
这种技术扩展了原型链污染的利用场景,即使在常规污染方式被防御的情况下,仍可能找到新的攻击路径。