Resumo do Item 88: Escreva métodos readObject defensivamente
Atenção: Com as evoluções do Java e práticas modernas, existem alternativas mais seguras e eficientes para lidar com serialização/desserialização. Mas como estamos estudando o livro vamos considerar para aprender. VER NO TÓPICO FINAL SOBRE SERIALIZAÇÃO Problema da Desserialização sem Defesa Uma classe pode ser tornada serializável apenas adicionando implements Serializable, mas isso pode comprometer suas invariantes. O método readObject age como um construtor público invisível, e precisa das mesmas precauções que um construtor tradicional. Se não for protegido, um invasor pode criar streams de bytes manipuladas para violar as invariantes da classe. Exemplo: uma classe Period pode ser manipulada para ter uma data final anterior à inicial. Ataque por Referência Mutável Um invasor pode fabricar uma stream de bytes que referencie os objetos mutáveis internos da classe. Ao modificar esses objetos (ex: Date), o estado da instância serializada pode ser alterado. Esse tipo de falha compromete a imutabilidade da classe, permitindo modificações após a criação. Soluções para um readObject Seguro Cópia defensiva de objetos mutáveis Sempre copie objetos mutáveis privados ao desserializar (Date, ArrayList, etc.). Exemplo: em vez de confiar em clone(), crie novas instâncias manualmente. Verificação de invariantes Após a cópia, verifique se os valores mantêm as regras da classe. Se alguma regra for violada, lance uma InvalidObjectException. Evitar métodos sobrescrevíveis Durante a desserialização, não chame métodos que possam ser sobrescritos por subclasses. Isso evita execução de código antes que a classe tenha sido completamente carregada. Alternativa: Padrão de Proxy de Serialização Sempre que possível, utilize serialização via proxy (Item 90). Esse padrão reduz a complexidade e minimiza riscos de falha na desserialização. Conclusão Trate readObject como um construtor público: valide e proteja os dados. Desconfie da stream de bytes: ela pode ter sido manipulada por um invasor. Sempre copie defensivamente objetos mutáveis para garantir a integridade da classe. Exemplos de código do livro:

Atenção: Com as evoluções do Java e práticas modernas, existem alternativas mais seguras e eficientes para lidar com serialização/desserialização. Mas como estamos estudando o livro vamos considerar para aprender. VER NO TÓPICO FINAL SOBRE SERIALIZAÇÃO
Problema da Desserialização sem Defesa
- Uma classe pode ser tornada serializável apenas adicionando implements Serializable, mas isso pode comprometer suas invariantes.
- O método readObject age como um construtor público invisível, e precisa das mesmas precauções que um construtor tradicional.
- Se não for protegido, um invasor pode criar streams de bytes manipuladas para violar as invariantes da classe.
- Exemplo: uma classe Period pode ser manipulada para ter uma data final anterior à inicial.
Ataque por Referência Mutável
- Um invasor pode fabricar uma stream de bytes que referencie os objetos mutáveis internos da classe.
- Ao modificar esses objetos (ex: Date), o estado da instância serializada pode ser alterado.
- Esse tipo de falha compromete a imutabilidade da classe, permitindo modificações após a criação.
Soluções para um readObject Seguro
Cópia defensiva de objetos mutáveis
- Sempre copie objetos mutáveis privados ao desserializar (Date, ArrayList, etc.).
- Exemplo: em vez de confiar em clone(), crie novas instâncias manualmente.
Verificação de invariantes
- Após a cópia, verifique se os valores mantêm as regras da classe.
- Se alguma regra for violada, lance uma InvalidObjectException.
Evitar métodos sobrescrevíveis
- Durante a desserialização, não chame métodos que possam ser sobrescritos por subclasses.
- Isso evita execução de código antes que a classe tenha sido completamente carregada.
Alternativa: Padrão de Proxy de Serialização
- Sempre que possível, utilize serialização via proxy (Item 90).
- Esse padrão reduz a complexidade e minimiza riscos de falha na desserialização.
Conclusão
Trate readObject como um construtor público: valide e proteja os dados.
Desconfie da stream de bytes: ela pode ter sido manipulada por um invasor.
Sempre copie defensivamente objetos mutáveis para garantir a integridade da classe.
Exemplos de código do livro: