Advanced 28 min readModule: Module 12: Advanced Web Exploitation: Prototype Pollution & SSRF
Advanced Web Exploitation: Prototype Pollution & SSRF
Deconstruct complex application vulnerabilities: Server-Side Prototype Pollution in Node.js leading to Remote Code Execution (RCE), Blind SSRF bypassing cloud metadata filters (`169.254.169.254`), and GraphQL query depth circular denial of service.
What You Will Learn in This Lesson
- How recursive object merge and `Object.assign` introduce Prototype Pollution via `__proto__` and `constructor.prototype`
- Escalating Prototype Pollution to Remote Code Execution (RCE) via `child_process.fork` environment gadgets
- Advanced SSRF exploitation against AWS/GCP/Azure Instance Metadata Services (IMDSv2)
- Securing GraphQL APIs against Batching Attacks and Circular Nested Query DoS
Introduction & Core Concept
While standard vulnerabilities like SQL Injection and Cross-Site Scripting (XSS) are widely understood, modern JavaScript stacks and cloud-native backends face subtle architectural exploit primitives. Server-Side Prototype Pollution allows attackers to inject properties into the root `Object.prototype`, corrupting application logic or hijacking subprocess execution. Server-Side Request Forgery (SSRF) abuses backend services into making unauthorized HTTP requests to internal cloud metadata APIs.
WHY DOES THIS MATTER IN THE REAL WORLD?
Capital One suffered one of the largest data breaches in history (100M+ customer records leaked) through a Server-Side Request Forgery (SSRF) attack that exfiltrated AWS IAM credentials from the EC2 metadata service.
Syntax & Structure
javascript
// Prototype Pollution Payload{"__proto__": {"shell": "/bin/sh", "NODE_OPTIONS": "--inspect"}}// AWS IMDSv2 Token Headercurl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"Simulating Prototype Pollution Gadget Hijacking and Hardening Defense
javascriptjavascript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647// Prototype Pollution Vulnerability & Defensive Mitigation Engineconst express = require('express');// VULNERABLE FUNCTION: Recursive deep merge without property sanitizationfunction vulnerableDeepMerge(target, source) {for (const key in source) {if (typeof source[key] === 'object' && source[key] !== null) {if (!target[key]) target[key] = {};vulnerableDeepMerge(target[key], source[key]);} else {target[key] = source[key];}}return target;}// HARDENED FUNCTION: Defensive Prototype-Safe Mergefunction secureDeepMerge(target, source) {for (const key in source) {// Block dangerous prototype poisoning keys!if (key === '__proto__' || key === 'constructor' || key === 'prototype') {continue;}if (typeof source[key] === 'object' && source[key] !== null) {if (!target[key]) target[key] = Object.create(null); // Dictionary with no prototype!secureDeepMerge(target[key], source[key]);} else {target[key] = source[key];}}return target;}// 1. Attacker Payload attempting to pollute global Object prototypeconst maliciousPayload = JSON.parse('{"__proto__": {"isAdmin": true, "role": "SUPERADMIN"}}');console.log("=== Server-Side Prototype Pollution Defense Engine ===");console.log("Global Object isAdmin before attack:", ({}).isAdmin); // undefined// Testing Safe Mergeconst userConfig = {};secureDeepMerge(userConfig, maliciousPayload);console.log("Global Object isAdmin after secure merge:", ({}).isAdmin); // undefined (Clean!)// Object.freeze prevention demonstrationObject.freeze(Object.prototype); // Locks root prototype permanently!console.log("✅ Object.prototype frozen permanently: System immune to prototype tampering!");
Line-by-Line Technical Breakdown
1IMDSv2 Defense: AWS EC2 Instance Metadata Service Version 2 (IMDSv2) mitigates SSRF by requiring a session-oriented `PUT` request with `X-aws-ec2-metadata-token-ttl-seconds` before metadata can be queried. Attackers exploiting simple `GET` SSRF cannot retrieve IAM credentials.
Try It Yourself (Interactive Editor)
Modify the code in real-time and click Run to test live browser output and console logs.
Intelligent Code Runner & Live Sandbox[JAVASCRIPT]
JAVASCRIPT SOURCE EDITOR
Interactive Live CodeCommon Mistakes & How to Avoid Them
#1: Relying on simple blacklist URL filters for SSRF (e.g. blocking `http://127.0.0.1`), which can be bypassed with DNS Rebinding or decimal IPs (`http://2130706433`).
Attackers register domain names with short TTL that resolve to a public IP first and a private IP (169.254.169.254) on subsequent lookups (DNS Rebinding).
Incorrect / Antipattern
if (url.includes('127.0.0.1')) block(); // Easily bypassed via 0.0.0.0 or DNS rebindingCorrect / Professional Solution
// Resolve DNS IP first, verify IP is not in private RFC1918 or link-local range, then fetchIndustry Best Practices & Professional Standards
- Execute `Object.freeze(Object.prototype)` at the entry point of Node.js microservices.
- Enforce IMDSv2 (`HttpTokens=required`) on all AWS EC2 and container instances.
- Use GraphQL query cost analysis and max depth limiters (e.g., `graphql-depth-limit`) to prevent nested query denial of service.
Lesson Summary & Core Takeaways
- Prototype Pollution corrupts global JavaScript object inheritance, leading to logic bypass and RCE.
- SSRF targets internal cloud metadata services to steal IAM credentials.
- Deep input validation, Object.freeze, and IMDSv2 mitigate advanced web attack vectors.