DEV Community

Java Efetivo (livro)
Java Efetivo (livro)

Posted on

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:

Image description

Image description

Image description

Image description

Image description

Image description

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs