π° Originally published on Securityelites β AI Red Team Education β the canonical, fully-updated version of this article.
π― BUG BOUNTY COURSE
FREE
Part of the Bug Bounty Mastery Course β 60 Days
Day 28 of 60 Β· 46.7% complete
β οΈ Authorised Targets Only. Test prototype pollution only against systems you own or have explicit written permission to test. All exercises target PortSwigger labs or your own local Node.js environment.
Prototype pollution is the bug that keeps paying β I have found it on three separate engagements on the same application category. My go-to detection is a quick URL probe; my first escalation step is always gadget hunting in the appβs JavaScript. I have found it on three separate engagements on the same application category β SPAs using JavaScript-heavy frontends with deep merge functions β because the root cause is almost always the same one-liner: an unsafe recursive merge that treats __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
Understand how prototype pollution works in JavaScript
Identify client-side and server-side pollution sinks
Chain client-side PP to DOM XSS via gadget chains
Escalate server-side PP to RCE in Node.js applications
Write a complete bug bounty report for a PP finding
β±οΈ 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 1. How Prototype Pollution Works 2. Client-Side PP β DOM XSS Chains 3. Server-Side PP β Node.js RCE 4. Finding Prototype Pollution in the Wild 5. Bug Bounty Report Structure 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.
PROTOTYPE POLLUTION β MECHANICSCopy
The vulnerable pattern β unsafe merge/deep clone
function merge(target, source) {
for (let key in source) {
if (typeof source[key] === βobjectβ) {
merge(target[key], source[key]); // VULNERABLE: target[key] can be proto
} else {
target[key] = source[key];
}
}
}
Attack payload pollutes Object.prototype
merge({}, JSON.parse(β{βprotoβ:{βpollutedβ:βyesβ}}β))
// Now: ({}).polluted === βyesβ β ALL objects inherit this
Three injection vectors
?proto[polluted]=yes # URL query parameter
{βprotoβ:{βpollutedβ:βyesβ}} # JSON body
?constructor[prototype][polluted]=yes # alternative path
Quick confirm in browser console
({}).polluted // should be undefined before, βyesβ after pollution
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.
CLIENT-SIDE PP β DOM XSS CHAINCopy
Step 1: Confirm prototype pollution via URL
https://target.com/?__proto__[testprop]=confirmed
Open DevTools Console: ({}).testprop β βconfirmedβ = polluted
Step 2: Search for gadgets in app JS
Look for patterns reading undefined properties into DOM sinks:
innerHTML = options.template // if template is undefined, reads from proto
eval(config.callback) // if callback polluted β XSS via eval
document.write(settings.html) // if html polluted β XSS
Step 3: Craft XSS payload via pollution
https://target.com/?__proto__[template]=
If app later does: el.innerHTML = options.template (where options has no template)
β reads from proto.template β XSS executes
Chrome DevTools β check prototype pollution
// In console after visiting the URL:
Object.prototype.template // returns your injected value if polluted
window.proto // inspect prototype chain
π οΈ EXERCISE 1 β BROWSER (20 MIN Β· NO INSTALL)
Research Disclosed Prototype Pollution Reports on HackerOne
β±οΈ 20 minutes Β· Browser only
π Read the complete guide on Securityelites β AI Red Team Education
This article continues with deeper technical detail, screenshots, code samples, and an interactive lab walk-through. Read the full article on Securityelites β AI Red Team Education β
This article was originally written and published by the Securityelites β AI Red Team Education team. For more cybersecurity tutorials, ethical hacking guides, and CTF walk-throughs, visit Securityelites β AI Red Team Education.

Top comments (0)