FREE
Part of the Bug Bounty Mastery Course — 60 Days
__proto__ as a normal property. Client-side prototype pollution can chain to DOM XSS. Server-side in Node.js can chain to RCE. The payloads are short, the impact is high, and most automated scanners miss it entirely. Here’s the complete Prototype Pollution Bug Bounty 2026 methodology.🎯 What You’ll Master in Day 28
⏱️ 40 min read · 3 exercises · Day 28 of 60
✅ Before You Start
- Day 27 — Path Traversal & LFI — input reaching a sensitive function on the filesystem. Prototype pollution works differently: attacker-controlled input modifies the JavaScript prototype chain. Same principle of “trust without validation,” different execution environment.
- Browser DevTools · PortSwigger Academy account · Node.js installed for server-side testing
📋 Day 28 — Prototype Pollution Bug Bounty
Prototype pollution sits in the web application security cluster alongside SSTI and path traversal — all three exploit server-side processing of attacker-controlled input. The Kali Linux Commands reference has the curl and Node.js invocation syntax for testing PP payloads in server-side contexts.
How Prototype Pollution Works
Every JavaScript object inherits properties from its prototype. My mental model for teaching this: think of Object.prototype as a shared notepad — if I write on it, everyone in the room can read what I wrote, whether or not I intended them to. Object.prototype is the root — properties added to it appear on every object. Prototype pollution occurs when an attacker can inject a property into Object.prototype via a path like __proto__, constructor.prototype, or prototype. Any code that later reads that property from any object will receive the attacker-controlled value — even code that has nothing to do with the original injection point.
Client-Side PP — DOM XSS Chains
Client-side prototype pollution by itself is a Medium finding in my reports. Chained to a DOM XSS gadget it becomes High or Critical — and I always attempt escalation before submitting. My first step after confirming client-side PP is always the gadget search. Chained to a DOM XSS gadget it becomes High or Critical. The chain: pollute a property that a DOM sink later reads without sanitisation — the sink executes your value as HTML or JavaScript. My first step after confirming client-side PP is always searching for gadgets in the application’s JavaScript files that read from polluted prototype properties into sinks like innerHTML, document.write, or eval.
⏱️ 20 minutes · Browser only
Real PP reports show the gadget chains, payloads, and escalation steps that earned the payout. Studying three reports before testing teaches more than hours of solo exploration.
hackerone.com/hacktivity → search “prototype pollution”
Filter: Resolved, last 18 months, High/Critical
Find 3 reports. For each note:
– What parameter was the injection point?
– Client-side or server-side?
– What was the gadget/escalation chain?
– Payout amount?
Step 2: Look for RCE escalations
Search “prototype pollution RCE” or “prototype pollution remote code”
Find 1 server-side Node.js PP → RCE chain.
What property was polluted to achieve RCE?
Step 3: Note payout ranges
What is the typical payout for:
– PP without gadget chain (standalone)?
– PP chained to XSS?
– PP escalated to RCE?
Document: 3 reports with injection points, chains, and payouts.
📸 Screenshot your 3 findings with chains and payouts. Share in #bug-bounty.
Server-Side PP — Node.js RCE
Server-side prototype pollution in Node.js is the highest-impact variant — and the one I find most in Express-based APIs. My confirmation technique for server-side is the status code gadget: it proves pollution without touching code execution. The pattern: a merge function in a server-side Express handler accepts user-controlled JSON, the merge pollutes Object.prototype, and a gadget elsewhere in the application reads the polluted property into a child process spawn or similar execution function. The classic escalation chain targets the shell property used by the child_process module.
⏱️ 25 minutes · portswigger.net/web-security/prototype-pollution
PortSwigger’s PP labs are the cleanest hands-on path from theory to confirmed technique. Work through the client-side labs first to build the gadget-hunting mental model.
Lab 1: DOM XSS via client-side prototype pollution
Find the pollution source in the URL parameter
Find the gadget that sinks the polluted value to innerHTML
Craft the XSS payload via pollution
What property name was the gadget?
Lab 2: DOM XSS via an alternative prototype pollution vector
The __proto__ key is blocked. What alternative path works?
(Hint: constructor.prototype)
Lab 3: Client-side prototype pollution via flawed sanitisation
The app tries to block __proto__. How does it fail?
What bypass works?
Lab 4: Server-side prototype pollution, remote code execution
Find the merge endpoint accepting user JSON
Confirm pollution via status code gadget
Escalate to RCE via execArgv gadget
What command did you run?
Document: completed lab names + the specific gadgets used in each.
📸 Screenshot completed lab confirmations. Share in #bug-bounty.
Finding Prototype Pollution in the Wild
My PP hunting checklist covers the three most reliable discovery paths: URL parameter fuzzing, JSON body injection in API endpoints, and static analysis of JavaScript source. I run all three in sequence on every SPA engagement.: URL parameter fuzzing, JSON body injection in API endpoints, and static analysis of the application’s JavaScript for vulnerable merge/clone patterns. The automated tools (PPScan, ppmap) are useful for initial discovery; manual gadget hunting is always required for escalation.
⏱️ 20 minutes · Node.js on Kali · your own test server
Build the vulnerable endpoint yourself, then exploit it. Seeing the code you’re attacking makes the vulnerability click in a way that lab exercises don’t.
cat > /tmp/vuln_pp.js << 'EOF' const express = require('express'); const app = express(); app.use(express.json());function merge(target, source) { for (let key in source) { if (typeof source[key] === 'object') merge(target[key] ||= {}, source[key]); else target[key] = source[key]; } }app.post('/api/update', (req, res) => {
merge({}, req.body);
res.json({status: ‘updated’});
});
app.get(‘/api/check’, (req, res) => {
const obj = {};
res.json({polluted: obj.polluted || ‘not polluted’});
});
app.listen(3000, () => console.log(‘Listening on 3000’));
EOF
cd /tmp && npm install express 2>/dev/null
node vuln_pp.js &
Step 2: Confirm the server is clean
curl http://localhost:3000/api/check
Expected: {“polluted”:”not polluted”}
Step 3: Pollute Object.prototype
curl -X POST http://localhost:3000/api/update \
-H ‘Content-Type: application/json’ \
-d ‘{“__proto__”:{“polluted”:”HACKED”}}’
Step 4: Confirm pollution persisted
curl http://localhost:3000/api/check
Expected: {“polluted”:”HACKED”}
Did it work?
Step 5: Clean up
kill %1 (stop the node server)
📸 Screenshot showing {“polluted”:”HACKED”} response. Share in #bug-bounty.
📋 Prototype Pollution Quick Reference — Day 28
🏆 Day 28 Complete — Prototype Pollution Bug Bounty
PP mechanics, client-side DOM XSS chains, server-side Node.js RCE escalation, discovery methodology, and report structure. Day 29 moves to mass assignment — a different JavaScript/API vulnerability class with similarly high impact and similar underdetection by automated scanners.
🧠 Quick Check
?__proto__[x]=test confirmed in DevTools. Searching the app’s JavaScript you find: el.innerHTML = opts.errorTemplate where opts is constructed without an errorTemplate property. What is the complete exploit payload and why does it work?
❓ Frequently Asked Questions
What is prototype pollution?
What is the difference between client-side and server-side prototype pollution?
How do you safely probe for server-side prototype pollution?
How is prototype pollution prevented?
What CVSS score does prototype pollution get?
Day 27: Path Traversal & LFI Bug Bounty
Day 29: Mass Assignment Bug Bounty
📚 Further Reading
- Day 27 — Path Traversal & LFI — The previous server-side input vulnerability in this series. Path traversal reaches the filesystem; prototype pollution reaches the prototype chain. Same root cause (unsafe input handling), completely different execution contexts.
- Web Application Security Hub — The complete web security cluster. Prototype pollution connects to injection vulnerabilities, IDOR, and broken access control — all share the “trust without validation” root cause that prototype pollution exploits.
- Kali Linux Commands Reference — curl syntax for testing JSON body injection endpoints, Node.js invocation for server-side PP testing, and ppmap installation and usage commands.
- PortSwigger — Prototype Pollution Learning Path — Eight labs covering the full PP attack surface from basic pollution to server-side RCE. The most comprehensive hands-on PP learning resource available.
- ppmap — Prototype Pollution Scanner — Automated prototype pollution detection for URL parameters with gadget detection. Useful for initial scanning; always follow up with manual gadget hunting for escalation.

