Capítulo 12: Serialização
A Serialização ainda é usada hoje, mas com muita cautela. Ela foi amplamente utilizada no passado para persistência de objetos e comunicação entre sistemas, mas devido a diversos problemas de segurança e eficiência, seu uso tem diminuído. Atualmente, frameworks modernos e tecnologias como JSON, XML, Protobuf e Avro são preferidos para troca de dados, pois são mais seguros, interoperáveis e eficientes. No entanto, a serialização Java ainda pode ser encontrada em sistemas legados e em aplicações que precisam de compatibilidade com tecnologias antigas. Se for realmente necessário usar serialização, recomenda-se adotar boas práticas de segurança, como filtragem de objetos e evitar desserialização de fontes não confiáveis. Item 85: Prefira alternativas à serialização Java O que é Serialização? Processo de transformar um objeto em uma sequência de bytes para armazenamento ou transmissão. Desserialização é o processo inverso, reconstruindo o objeto a partir dos bytes serializados. Utiliza a interface Serializable no Java. Problemas da Serialização Java 1. Superfície de Ataque Grande O método readObject atua como um "construtor mágico", podendo instanciar objetos inesperados. Qualquer classe que implemente Serializable pode ser um ponto de exploração. 2. Vulnerabilidades de Segurança Possibilidade de execução remota de código (RCE) ao desserializar objetos de origem desconhecida. Uso de gadgets (métodos chamados automaticamente durante a desserialização) para criar cadeias de ataque. 3. Bombas de Desserialização Objetos que exigem grande poder computacional para serem desserializados. Exemplo: HashSet profundamente aninhado. Exemplo de bomba de desserialização: import java.io.*; import java.util.HashSet; public class DeserializationBomb { public static void main(String[] args) throws Exception { HashSet root = new HashSet(); HashSet s1 = root; HashSet s2; for (int i = 0; i < 100; i++) { s2 = new HashSet(); s1.add(s2); s1 = s2; } try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("bomb.ser"))) { out.writeObject(root); } } } Alternativas à Serialização Java JSON Leve, legível e amplamente suportado. Exemplo com Gson: import com.google.gson.Gson; class Pessoa { String nome; int idade; } public class JsonExample { public static void main(String[] args) { Gson gson = new Gson(); Pessoa pessoa = new Pessoa(); pessoa.nome = "João"; pessoa.idade = 30; String json = gson.toJson(pessoa); System.out.println(json); } } Protocol Buffers (Protobuf) Binário e eficiente. Necessita da definição de esquemas .proto. Como Mitigar Riscos se a Serialização for Necessária Evite Desserialização de Dados Não Confiáveis Use Filtragem de Objetos (ObjectInputFilter desde Java 9) ObjectInputFilter filter = info -> { if (info.serialClass() != null && info.serialClass().getName().equals("MinhaClasseSegura")) { return ObjectInputFilter.Status.ALLOWED; } return ObjectInputFilter.Status.REJECTED; }; ObjectInputStream ois = new ObjectInputStream(new FileInputStream("objeto.ser")); ois.setObjectInputFilter(filter); Object obj = ois.readObject(); Utilize Lista Branca em vez de Lista Negra Permita apenas classes explícitas na desserialização. Conclusão Evite ao máximo a Serialização Java em sistemas novos. Prefira formatos mais seguros e eficientes como JSON e Protobuf. Se precisar desserializar objetos, use filtragem rigorosa para evitar ataques. Exemplo do livro:

A Serialização ainda é usada hoje, mas com muita cautela. Ela foi amplamente utilizada no passado para persistência de objetos e comunicação entre sistemas, mas devido a diversos problemas de segurança e eficiência, seu uso tem diminuído.
Atualmente, frameworks modernos e tecnologias como JSON, XML, Protobuf e Avro são preferidos para troca de dados, pois são mais seguros, interoperáveis e eficientes. No entanto, a serialização Java ainda pode ser encontrada em sistemas legados e em aplicações que precisam de compatibilidade com tecnologias antigas.
Se for realmente necessário usar serialização, recomenda-se adotar boas práticas de segurança, como filtragem de objetos e evitar desserialização de fontes não confiáveis.
Item 85: Prefira alternativas à serialização Java
O que é Serialização?
- Processo de transformar um objeto em uma sequência de bytes para armazenamento ou transmissão.
- Desserialização é o processo inverso, reconstruindo o objeto a partir dos bytes serializados.
- Utiliza a interface Serializable no Java.
Problemas da Serialização Java
1. Superfície de Ataque Grande
- O método readObject atua como um "construtor mágico", podendo instanciar objetos inesperados.
- Qualquer classe que implemente Serializable pode ser um ponto de exploração.
2. Vulnerabilidades de Segurança
- Possibilidade de execução remota de código (RCE) ao desserializar objetos de origem desconhecida.
- Uso de gadgets (métodos chamados automaticamente durante a desserialização) para criar cadeias de ataque.
3. Bombas de Desserialização
- Objetos que exigem grande poder computacional para serem desserializados.
- Exemplo: HashSet profundamente aninhado.
Exemplo de bomba de desserialização:
import java.io.*;
import java.util.HashSet;
public class DeserializationBomb {
public static void main(String[] args) throws Exception {
HashSet
Alternativas à Serialização Java
JSON
- Leve, legível e amplamente suportado. Exemplo com Gson:
import com.google.gson.Gson;
class Pessoa {
String nome;
int idade;
}
public class JsonExample {
public static void main(String[] args) {
Gson gson = new Gson();
Pessoa pessoa = new Pessoa();
pessoa.nome = "João";
pessoa.idade = 30;
String json = gson.toJson(pessoa);
System.out.println(json);
}
}
Protocol Buffers (Protobuf)
- Binário e eficiente.
- Necessita da definição de esquemas .proto.
Como Mitigar Riscos se a Serialização for Necessária
- Evite Desserialização de Dados Não Confiáveis
- Use Filtragem de Objetos (ObjectInputFilter desde Java 9)
ObjectInputFilter filter = info -> {
if (info.serialClass() != null && info.serialClass().getName().equals("MinhaClasseSegura")) {
return ObjectInputFilter.Status.ALLOWED;
}
return ObjectInputFilter.Status.REJECTED;
};
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("objeto.ser"));
ois.setObjectInputFilter(filter);
Object obj = ois.readObject();
Utilize Lista Branca em vez de Lista Negra
- Permita apenas classes explícitas na desserialização.
Conclusão
- Evite ao máximo a Serialização Java em sistemas novos.
- Prefira formatos mais seguros e eficientes como JSON e Protobuf.
- Se precisar desserializar objetos, use filtragem rigorosa para evitar ataques.
Exemplo do livro: