prototype-pollution
Skill1 starsChanged 11 days agoMITView on GitHub
Hunt for JavaScript prototype pollution: client-side pollution via __proto__/constructor.prototype in URL params or merge/clone utilities, and server-side pollution (Node.js) via unsafe object-merge/extend operations on user-controlled JSON, escalating to DoS, property injection, or RCE via gadget chains. Use when the stack is JavaScript/Node-based, or client-side JS uses deep-merge/clone/extend utilities on URL or form data. Keywords: prototype pollution, __proto__, constructor.prototype, lodash merge, jQuery extend, Node.js RCE gadget. Do NOT use for mass assignment against ORM models (different mechanism, same "extra keys" smell) — use mass-assignment.
- Sends data out
10 other projects use a version of this.
Adopted by
Most recently taken up by
- awarexone/AXguardtheir own version, first seen Sep 15, 2026
- ajtazer/heckittheir own version, first seen Sep 11, 2026
- emre-guler/websectheir own version, first seen Aug 27, 2026
- conjure-3301/skillstheir own version, first seen Aug 17, 2026
- Kur1sulab/blackboxtheir own version, first seen Aug 12, 2026
- thejefflarson/soundchecktheir own version, first seen Jul 31, 2026
Used with
Projects with it also use path-traversal, sql-injection and 1 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
langbyyiSkillpath-traversal
Path traversal and LFI playbook. Use when file paths, download endpoints, include operations, archive extraction, or wrapper behavior may expose filesystem control.
Also in 4 projects that use this
YepAPISkillsql-injection
SQL injection prevention — parameterized queries, ORM safety, dynamic query guards.
Also in 3 projects that use this
blacklanternsecuritySkillcommand-injection
Guide OS command injection exploitation during authorized penetration testing.
Also in 3 projects that use this
Other versions10 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 10
- yaklang/hack-skills★ 2.4ksame name
- thejefflarson/soundcheck★ 20same name
- awarexone/AXguard★ 17same name
- langbyyi/websec-skills★ 4same name
- Kur1sulab/blackbox★ 3same name
- ajtazer/heckit★ 2same name
- emre-guler/websec★ 2same name
- JustineDevs/premortem★ 2same name
- KaanBicaklar/mona-sast-skills★ 2same name
- conjure-3301/skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository124 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- ai-agent-reconSkill
- ai-supply-chainSkill
- exfiltration-via-aiSkill
- indirect-injectionSkill
- llm-fuzzingSkill
- prompt-injectionSkill
- rag-poisoningSkill
- tool-abuseSkill
- chain-analysisSkill
- chain-auth-to-takeoverSkill
- chain-customSkill
- chain-graph-walkSkill
- chain-idor-to-mass-dataSkill
- chain-info-to-exploitSkill
- chain-multi-appSkill
- chain-ssrf-to-cloudSkill
- chain-web-to-rceSkill
- chain-xss-to-account-takeoverSkill
- email-securitySkill
- engagement-flowSkill
- finding-disciplineSkill
- http-headers-securitySkill
- oob-interactionsSkill
- opsec-disciplineSkill
- research-firstSkill
- scope-disciplineSkill
- scope-importSkill
- session-contextSkill
- 2fa-bypassSkill
- api-abuseSkill
- auth-bypassSkill
- broken-access-controlSkill
- business-logicSkill
- cache-poisoningSkill
- clickjackingSkill
- corsSkill
- credential-testingSkill
- crlf-injectionSkill
- cryptographic-oracleSkill
- csrfSkill
- css-injectionSkill
- data-exfiltration-testSkill
- deserializationSkill
- email-injectionSkill
- file-uploadSkill
- fuzzingSkill
- graphqlSkill
- grpcSkill
- host-headerSkill
- http-smugglingSkill
- idorSkill
- info-disclosureSkill
- jwtSkill
- lateral-movementSkill
- lfi-rfiSkill
- mass-assignmentSkill
- oauthSkill
- open-redirectSkill
- parameter-pollutionSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
3 rules. 0 are common, 2 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 9 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 55
Client-side impact — DOM XSS via polluted sink: If pollution is confirmed, check whether any app-wide default (e.g.
- Distinctive: line 69
Follow up with an unrelated, simple request to see if global behavior changed (e.g.
- Distinctive: line 120
Before declaring this finding complete, probe these escalation paths:
“Common” is measured: kept by at least 6 in 10 of the 9 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Signals
- Client-side JS bundle imports
lodash(merge,defaultsDeep,set),jQuery.extend,$.extend(true, ...), or a hand-rolled recursive merge/clone function. - URL query/fragment parameters parsed into an options object that's then merged with app defaults (common in client-side routers/config parsers).
- Node.js backend (
Server: Express/X-Powered-By: Express, or JSON API returning Node stack traces) accepting deeply nested JSON bodies that get merged into config/session/user objects. - Libraries with known historical prototype-pollution CVEs in use at an old version:
lodash< 4.17.21,jquery< 3.4.0,minimist< 1.2.6,qswith certain configs,hoek,deep-extend— checkpackage.json/bundled version strings if exposed.
Prerequisites
- For client-side: browser DevTools console access on the target origin.
- For server-side: ability to send arbitrary nested JSON bodies and observe either direct output reflecting polluted state, or indirect effects (error messages, timing, behavior change) since server-side pollution is usually blind.
Methodology
- Client-side detection — manual console probe. On any page, before sending payloads, check if the prototype is already polluted by benign app behavior, then test an injection point (URL param parsed into an options object):
Try common client-side injection vectors via URL:// in browser devtools console, on the target origin console.log(Object.prototype.polluted); // should be undefined initially
Then reload the page in a real browser and check in console:curl -s "https://target.com/?__proto__[polluted]=1" curl -s "https://target.com/?__proto__.polluted=1" curl -s "https://target.com/#__proto__[polluted]=1"console.log(Object.prototype.polluted); // "1" if polluted - Client-side impact — DOM XSS via polluted sink. If pollution is confirmed, check whether any app-wide default (e.g. a template-rendering option,
innerHTMLsink config, a "trusted" flag) reads from a prototype-inherited property that you can now control:
This step is target-specific — requires reading the actual bundle to find a real gadget (a property read viacurl -s "https://target.com/?__proto__[transform_url]=javascript:alert(document.domain)"obj.someFlagwhereobjdoesn't own that property), not guessing blindly. - Server-side detection — timing/error-based (blind). Send a JSON body attempting to pollute
Object.prototypethrough a nested merge, then probe for side effects on a separate, unrelated request:
Follow up with an unrelated, simple request to see if global behavior changed (e.g. if you polluted a property that affects content-type handling, JSON parsing, or templating):curl -s -i -X POST "https://target.com/api/profile" -H "Content-Type: application/json" \ -d '{"__proto__": {"polluted": "yes"}}' # or via constructor chain, bypassing naive __proto__ key filters curl -s -i -X POST "https://target.com/api/profile" -H "Content-Type: application/json" \ -d '{"constructor": {"prototype": {"polluted": "yes"}}}'curl -s -i "https://target.com/api/health" - Server-side — crash/DoS confirmation (safe, strong signal). A very reliable low-risk confirmation technique is polluting a property with a type that breaks a later
JSON.stringify/array operation app-wide, causing a 500 on a subsequent unrelated request:
A 500 appearing on a previously-200 unrelated endpoint, immediately after the pollution attempt and not before, is strong server-side evidence.curl -s -i -X POST "https://target.com/api/profile" -H "Content-Type: application/json" \ -d '{"__proto__": {"toJSON": "polluted"}}' curl -s -i "https://target.com/api/health" # expect 500 if pollution propagated - Gadget hunting for RCE (Node-specific, deep). If the app uses
child_process, template engines (ejs,pug,handlebars), or certain ORMs, known gadget chains exist where a polluted property (e.g. a template engine'soutputFunctionNameor a NodeNODE_OPTIONS-style escalation in some deployment configs) can be weaponized to RCE. This requires source/dependency visibility — identify the exact library+version in use and cross-reference public gadget-chain writeups for that specific library before attempting, rather than guessing generically. Any RCE attempt is destructive and requires an operator gate per project rules. - Scanner-assisted sweep across many endpoints once a manual positive is found, to scope how many sinks are affected:
(Use whichever maintained PP scanner is available in the environment; verify itsnode server-side-prototype-pollution/ppmap.js -u https://target.com/api/profile -X POST \ -b '{"username":"test"}' -p '{json-body}'--helpoutput first per project CLAUDE.md before trusting flags.)
Tooling
- Browser DevTools console for client-side confirmation (
Object.prototype). curlfor raw JSON body crafting against API endpoints.- Known server-side prototype pollution scanners (e.g. community
ppmap/server-side-prototype-pollutiontooling) for sweeping multiple endpoints after manual confirmation. - Dependency version fingerprinting (
package-lock.jsonif leaked,X-Powered-By, bundled source maps) to match against known-CVE library versions.
Root Causes
- Recursive merge/clone/set utility (
lodash.merge,jQuery.extend(true, ...), hand-rolled deep merge) does not block__proto__,constructor, andprototypeas key names before assigning into the target object. - Server-side code merges user-supplied JSON directly into a long-lived object (config, template locals, session defaults) that affects later, unrelated requests — polluting the shared
Object.prototyperather than a request-scoped object. - Outdated vulnerable versions of common merge/query-parsing libraries still in use.
Validation Gate (minimum proof)
- Client-side: console output showing
Object.prototype.<key>set to an attacker-chosen value purely from a URL/query parameter, plus (for a real finding, not just a PoC) a concrete gadget showing it affects app behavior (DOM XSS, auth bypass flag, etc.) — pollution alone without a gadget is Inferred/low severity. - Server-side: request/response pair showing a separate, subsequent, unrelated request behaving differently (error, data leak, behavior change) only after the pollution payload was sent — the before/after pairing across two distinct requests is the core proof.
- For any RCE claim: an actual command execution proof equivalent to other RCE skills (e.g.
curloutput of a benign command), gated by operator approval before invocation.
Gotchas
- Minimum proof: successfully setting
Object.prototype.polluted = "1"with no observable downstream effect is Inferred, not Demonstrated — you need a gadget. - Common N/A: app uses
Object.create(null)orMapinstead of plain objects for merge targets, or a merge library patched to block__proto__/constructor/prototypekeys (lodash ≥4.17.21+ with the fix) — verify the exact version before concluding, don't assume from "it's lodash so it's probably fine" either way. - Overclaim trap: finding a client-side pollution with no exploitable gadget is low/informational — don't inflate it to "RCE" just because prototype pollution can lead to RCE on Node elsewhere; you must show the actual gadget for this target.
- Server-side pollution is almost always blind — resist the temptation to assume success from a lack of error; actively probe a second request for the behavior change.
- Respect the project's human-gate rule before attempting any RCE gadget chain — pollution-to-RCE is exploitation, not hunting.
Chain Anchors
Before declaring this finding complete, probe these escalation paths:
- RCE via polluted gadget — Can the polluted prototype property reach a server-side gadget (template engine, child_process) for RCE?
- Client-side XSS via DOM gadget — Does the pollution reach a DOM sink (innerHTML, src) to achieve XSS?
- Auth/permission bypass via polluted defaults — Can you pollute a default config property (isAdmin, role) that a later check trusts?
- Denial of service — Does polluting core Object.prototype properties crash or degrade the application?
A finding without chain anchor results is INCOMPLETE. Record each anchor as tested/not-applicable/blocked with the reason.
Chains & Compositions
- Client-side pollution of a security-relevant default (e.g. a "trusted domains" list read via prototype fallback) → DOM XSS/SSRF, chain into whatever client-side injection class applies.
- Server-side pollution of an auth/role default property → privilege escalation, chain with broken-access-control.
- Server-side pollution reaching a template engine gadget → RCE, the most severe outcome, requires operator gate.
- Pollution via a JSON body merge that resembles mass assignment surface → cross-reference mass-assignment when the same endpoint is vulnerable to both.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

