Deserialização insegura
1. Introdução à Deserialização Insegura
Serialização é o processo de converter objetos ou estruturas de dados em um formato que pode ser armazenado ou transmitido (como uma string ou bytes). Deserialização é o processo inverso: reconstruir o objeto original a partir desse formato serializado.
A deserialização insegura ocorre quando uma aplicação desserializa dados recebidos de fontes não confiáveis sem validação adequada. Isso permite que um atacante injete objetos maliciosos que podem alterar o fluxo de execução do programa, levando a ataques como execução remota de código (RCE), negação de serviço (DoS) ou bypass de autenticação.
Este vetor de ataque frequentemente se relaciona com Server-Side Request Forgery (SSRF) e XML External Entity (XXE), pois a deserialização pode ser usada como ponto de entrada para explorar outras vulnerabilidades na infraestrutura.
2. Como Funciona o Ataque de Deserialização Insegura
O mecanismo básico envolve a injeção de um objeto serializado malicioso que, ao ser desserializado, executa código arbitrário ou manipula o estado da aplicação.
Exemplo simplificado em PHP
<?php
class MaliciousClass {
public $command = 'id';
public function __wakeup() {
system($this->command);
}
}
// Payload malicioso criado pelo atacante
$payload = 'O:14:"MaliciousClass":1:{s:7:"command";s:2:"id";}';
$object = unserialize($payload); // Executa system("id")
?>
Exemplo simplificado em Java
import java.io.*;
public class Exploit implements Serializable {
private void readObject(ObjectInputStream ois) throws Exception {
ois.defaultReadObject();
Runtime.getRuntime().exec("calc.exe");
}
}
// Código vulnerável
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("dados.bin"));
Object obj = ois.readObject(); // Executa código malicioso
Diferença entre payloads e gadget chains
- Payloads diretos: O atacante controla diretamente a classe que será desserializada (raro em aplicações reais).
- Gadget chains: O atacante usa classes existentes na aplicação que, quando combinadas em uma sequência específica, executam código malicioso.
3. Principais Linguagens e Bibliotecas Vulneráveis
PHP
unserialize() com entrada controlada pelo usuário é extremamente perigoso. A função __wakeup() e __destruct() podem ser exploradas.
// Código vulnerável
$data = $_GET['data'];
$object = unserialize($data); // NUNCA faça isso!
Java
ObjectInputStream.readObject() é o método clássico. Bibliotecas como Jackson (com enableDefaultTyping()), XStream e Fastjson também apresentam vulnerabilidades conhecidas.
// Jackson vulnerável
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
Object obj = mapper.readValue(jsonString, Object.class);
Python
pickle.loads() é inerentemente inseguro com dados não confiáveis. yaml.load() também permite execução de código arbitrário.
import pickle
import yaml
# Perigoso
data = b"cos\nsystem\n(S'id'\ntR."
pickle.loads(data)
# Perigoso
yaml.load("!!python/object/apply:os.system ['id']")
.NET
BinaryFormatter.Deserialize(), JavaScriptSerializer.Deserialize() e LosFormatter são vulneráveis quando usados com dados não confiáveis.
// Código vulnerável em C#
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream(data);
object obj = formatter.Deserialize(stream);
4. Gadget Chains e Exploração Avançada
Gadget chains são sequências de classes legítimas presentes no classpath da aplicação que, quando encadeadas, permitem execução de código arbitrário. O atacante não precisa injetar classes próprias; ele apenas constrói um objeto serializado que, ao ser desserializado, ativa a cadeia.
Exemplo real: Apache Commons Collections
A biblioteca Apache Commons Collections possui classes como InvokerTransformer e ChainedTransformer que, combinadas, permitem executar qualquer método em qualquer objeto.
// Gadget chain simplificada
Transformer[] transformers = new Transformer[] {
new ConstantTransformer(Runtime.class),
new InvokerTransformer("getMethod",
new Class[] {String.class, Class[].class},
new Object[] {"getRuntime", new Class[0]}),
new InvokerTransformer("invoke",
new Class[] {Object.class, Object[].class},
new Object[] {null, new Object[0]}),
new InvokerTransformer("exec",
new Class[] {String.class},
new Object[] {"calc.exe"})
};
Transformer chain = new ChainedTransformer(transformers);
Ferramentas de exploração
- ysoserial: Gera payloads para Java (suporta múltiplas gadget chains como CommonsCollections, Spring, Jackson)
- PHPGGC: Gera gadget chains para PHP
- gadgetinspector: Ferramenta da Cisco para encontrar gadget chains em código Java
5. Consequências de uma Deserialização Bem-Sucedida
- Execução remota de código (RCE): O atacante executa comandos no servidor
- Escalação de privilégios: Acesso a funcionalidades restritas
- Movimentação lateral: Uso do servidor comprometido para atacar outros sistemas
- Exfiltração de dados: Leitura de arquivos sensíveis ou bases de dados
- Negação de serviço (DoS): Criação de objetos que consomem recursos infinitos
6. Boas Práticas de Prevenção para Desenvolvedores
Nunca desserializar dados de fontes não confiáveis
Esta é a regra mais importante. Se possível, evite completamente a deserialização de dados externos.
Uso de formatos seguros
Prefira JSON com bibliotecas seguras:
// Python seguro
import json
data = json.loads(trusted_input) # Não permite execução de código
// Java seguro com Jackson
ObjectMapper mapper = new ObjectMapper();
MyClass obj = mapper.readValue(json, MyClass.class); // Sem default typing
Implementação de allowlists
Valide o tipo de objeto antes de desserializar:
// PHP com allowlist
$allowed_classes = ['User', 'Product'];
$object = unserialize($data, ['allowed_classes' => $allowed_classes]);
Alternativas seguras
- Python: Use
pickleapenas para dados internos - Rust: Use
serdecom tipos estáticos - Java: Considere usar protocol buffers ou JSON em vez de serialização nativa
7. Medidas de Mitigação em Arquitetura e Infraestrutura
Isolamento de processos
Execute serviços que realizam deserialização em contêineres ou sandboxes com privilégios mínimos.
Monitoramento e logging
Implemente detecção de tentativas de deserialização suspeitas:
// Exemplo de log para análise
2024-01-15 10:30:45 WARN Deserialization attempt from IP 192.168.1.100
Payload size: 45KB, Object type: java.util.HashMap
Atualização de dependências
Mantenha bibliotecas atualizadas e remova aquelas com gadget chains conhecidas (ex: versões antigas do Apache Commons Collections).
Uso de WAF
Configure regras para bloquear payloads comuns de deserialização:
# Regra ModSecurity para detectar payloads PHP
SecRule ARGS "@rx O:\d+:" "id:12345,phase:2,deny,status:403"
8. Testes e Validação de Segurança Contra Deserialização
Testes manuais
Identifique endpoints que aceitam dados serializados (formato binário, base64, XML, YAML) e teste com payloads conhecidos.
Ferramentas de scanning
Burp Suite com extensões como "Java Deserialization Scanner" ou "PHP unserialize Payload Generator".
Exemplo de teste de penetração
# Envio de payload PHP para teste
GET /api/user?data=O:14:"MaliciousClass":0:{} HTTP/1.1
Host: vulnerable-app.com
# Resposta esperada se vulnerável: erro ou execução de código
Checklist de revisão de código
- [ ] Identificar todas as funções de deserialização (
unserialize,pickle.loads,readObject) - [ ] Verificar se a entrada é controlada pelo usuário
- [ ] Avaliar se há validação de tipo ou allowlists
- [ ] Verificar dependências com gadget chains conhecidas
- [ ] Testar com payloads de deserialização
Referências
- OWASP Deserialization Cheat Sheet — Guia completo de prevenção contra deserialização insegura, com exemplos para múltiplas linguagens
- CWE-502: Deserialization of Untrusted Data — Definição oficial da vulnerabilidade no Common Weakness Enumeration
- ysoserial - GitHub — Ferramenta de prova de conceito para geração de payloads de deserialização em Java
- PHPGGC - GitHub — Biblioteca de gadget chains para exploração de unserialize() em PHP
- Jackson Deserialization Vulnerabilities — Issues de segurança oficiais do Jackson Databind, com exemplos de CVEs
- SANS: Deserialization Attacks — Artigo técnico detalhando mecanismos de ataque e defesa contra deserialização
- PortSwigger: Deserialization — Tutorial interativo do Burp Suite sobre exploração de deserialização insegura