Skip to main content

prototype-pollution

Hunt JavaScript prototype pollution (CWE-1321) — the 2023-2026 meta-vulnerability that chains into RCE, auth bypass, and SSRF on most Node.js stacks.

Aller à l'installation

Informations de source

Dépôt
BitterSecurity/Decepticon
Dernière activité de la source
2 juin 2026 à 17:42
Langue détectée de SKILL.md
anglais
Étoiles
5 565
Forks
1 053

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
prototype-pollution
description
Hunt JavaScript prototype pollution (CWE-1321) — the 2023-2026 meta-vulnerability that chains into RCE, auth bypass, and SSRF on most Node.js stacks.
metadata
{"subdomain":"web-exploitation","when_to_use":"javascript prototype pollution cwe-1321 node js __proto__ constructor chain rce auth bypass ssrf gadget"}
# Prototype Pollution Playbook Prototype pollution is the JavaScript equivalent of a universal gadget: plant a property on `Object.prototype` and it appears on every object in the runtime. Worthless in isolation, deadly in chain (`__proto__.isAdmin = true` → auth bypass; `__proto__.shell = "/bin/bash"` → RCE via `spawn`). ## 1. Sinks — the libraries that still introduce sinks Keep a running list per engagement. These continue to ship sinks in 2026: - **Deep-merge:** `lodash.merge`, `deepmerge` (pre-fix), `merge-deep`, `deepExtend`, `hoek.merge`, `mixme` - **Deep-clone:** `lodash.defaultsDeep`, `lodash.zipObjectDeep`, `set-value` (pre-3.0.3) - **URL-to-obj:** `qs`, `express-fileupload`, `jquery.extend(true, ...)` - **Config loaders:** `node-config` recursive merge, `dotenv-extended`, `rc` - **Template engines:** Handlebars helpers fed from untrusted ctx ```bash # Every JS/TS project: sweep known-bad versions jq '.dependencies,.devDependencies | to_entries[] | select(.key | test("merge|lodash|set-value|dot-object|dot-prop|node-pg"))' /workspace/src/package.json npm ls lodash set-value dot-prop 2>/dev/null | grep -E '[0-9]' ``` ## 2. Sources Any user input deserialized into a nested object: - JSON body parsers (`body-parser`, `express.json`) - Query string parsers (`qs` with default config parses `a[b][__proto__][c]=1`) - YAML uploads - Form-data / multipart ## 3. Audit workflow 1. Find every deep merge call site. 2. Trace each one backwards — is the right-hand object user-controlled? 3. If yes: check the merge function's prototype-pollution fix version. 4. Even if the merge is fixed, check whether a *copy* (lodash.set, dot-path-value, jsonpath.set) creates a pollution path. ## 4. Exploitation gadgets Poisoning `Object.prototype` doesn't do anything by itself — you need a gadget that reads a property that didn't exist before. Classic gadgets: - **`child_process.spawn(cmd, args, opts)`** — opts has a `shell` option. Poison `__proto__.shell = "/bin/bash"` then any subsequent spawn call executes through bash and interprets args as shell strings. - **Express middleware** — most middlewares check `options.someFlag` with `if (opts.someFlag)`. Poisoning that flag flips security defaults. - **Templating** — Handlebars and EJS read `helpers` and `partials` from the context object; pollution adds helpers that execute code. - **`lodash.template`** — if the template source is built from `_.template(tpl, ctx)` you can inject via polluted `escape`/`evaluate` keys. - **`mongoose`** — polluting `Schema.Types` causes subsequent schema definitions to use attacker-controlled types. ## 5. PoC template ```bash # Classic lodash.merge RCE via child_process.spawn curl -X POST https://target.com/api/settings \ -H 'Content-Type: application/json' \ -d '{"__proto__": {"shell": "/bin/bash", "env": {"PATH": "/tmp:/usr/bin"}}}' # Second request triggers the gadget curl https://target.com/api/render-pdf # → any subsequent child_process.spawn call now runs through /bin/bash ``` ## 6. Success signals for `validate_finding` - Server error with stack trace referencing `Object.prototype` - Output of injected command reflected in next response - Admin-only endpoint now returns 200 after poisoning `__proto__.isAdmin` Negative control: same payload with `proto` (no leading underscores) — should have no effect. If it does, the endpoint is treating that key specially and the finding is unrelated. ## 7. Default CVSS | Variant | Vector | Score | |---------------------------------------|----------------------------------------------|-------| | DoS (crash Node process) | AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H | 7.5 | | Auth bypass via `isAdmin` pollution | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N | 9.1 | | RCE via spawn gadget | AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H | 10.0 | ## 8. Chain promotion Prototype pollution is almost always the *first* hop of a chain. After validation, add an `enables` edge from the pollution vuln to: - the spawn / template gadget vuln (RCE chain) - the auth check vuln (privilege escalation chain) - the SSRF vuln if the downstream request lib has an options pollution surface Chain weight 0.4 — pollution is cheap once the merge sink is known.
Voir sur GitHub