flawopen.com/Desserialização insegura/.NET BinaryFormatter: segurança
O BinaryFormatter do .NET é seguro?
A Microsoft afirma que BinaryFormatter é inseguro e não pode ser tornado seguro. Recomenda parar de usá-lo mesmo quando o aplicativo acredita que os dados são confiáveis. No .NET 9, os tipos da API continuam presentes, mas a implementação integrada sempre lança PlatformNotSupportedException; runtimes antigos e o pacote de compatibilidade sem suporte ainda têm o risco original.
// Não desserialize dados que cruzam uma fronteira de confiança. using System.IO; using System.Runtime.Serialization.Formatters.Binary; public static class LegacyReader { public static object Deserialize(Stream input) => new BinaryFormatter().Deserialize(input); } // Outros formatadores polimórficos irrestritos a remover: SoapFormatter NetDataContractSerializer LosFormatter ObjectStateFormatter // usado internamente no ViewState do ASP.NET // SerializationBinder não torna esses formatos seguros.
// A forma dos dados é declarada pelo código da aplicação. // Nullable reference types make the DTO contract explicit. #nullable enable using System; using System.IO; using System.Text.Json; public sealed record MyDto(int Id, string Name); public static class DtoReader { public static MyDto Parse(ReadOnlySpan<byte> json) { // Limite o tamanho da entrada e valide as regras da aplicação. if (json.Length > 65_536) throw new InvalidDataException(); MyDto? value = JsonSerializer.Deserialize<MyDto>(json); if (value is null || value.Id <= 0 || string.IsNullOrWhiteSpace(value.Name) || value.Name.Length > 100) throw new InvalidDataException(); return value; } } // Para arquivos NRBF antigos, use NrbfDecoder para inspecionar // registros e mapear valores permitidos para um DTO. // Nunca recrie tipos arbitrários do runtime.
Por que BinaryFormatter é perigoso
BinaryFormatter.Deserialize reconstrói grafos de objetos a partir de um fluxo e pode permitir que dados controlados por um atacante influenciem o fluxo de execução. A Microsoft alerta para negação de serviço, divulgação de informações e execução remota de código. O problema central é a desserialização polimórfica irrestrita: os dados serializados podem influenciar quais tipos e estados de objetos serão processados. Nenhuma opção do formatador o transforma em um analisador seguro de bytes não confiáveis.
O risco não se limita a endpoints HTTP públicos. Arquivos, cache, filas, registros de banco, mensagens de clientes desktop e estado sincronizado na nuvem podem ser influenciados por um atacante posteriormente. Rastreie como os bytes entram e circulam no sistema; “nós gravamos isso” ou “é interno” não é uma classificação permanente de confiança.
Por que SerializationBinder não resolve
Um SerializationBinder personalizado pode restringir os tipos que o formatador tenta resolver, mas a Microsoft diz explicitamente que binder ou outra opção de configuração não mitigam ataques de negação de serviço e podem ser insuficientes contra outras classes de ataque. Binder não substitui a migração; não aceite entrada não confiável enquanto aguarda a remoção do BinaryFormatter.
Localize usos antigos e caminhos relacionados
Pesquise no código, nas referências dos projetos e na configuração do runtime por BinaryFormatter, IFormatter, SoapFormatter, NetDataContractSerializer, LosFormatter e ObjectStateFormatter. Inspecione provedores de sessão, adaptadores de cache, consumidores de filas, importação/exportação de arquivos e aplicações ASP.NET Web Forms antigas. O ViewState normalmente é protegido por código de autenticação de mensagem (MAC); mantenha essa proteção ativa e proteja a machine key. Esse MAC não torna segura a desserialização genérica com BinaryFormatter.
Planeje a migração pelo formato e pela versão do runtime
Para novos dados, escolha um contrato explícito como System.Text.Json, DataContractSerializer, MessagePack ou protobuf-net conforme compatibilidade e formato; não há substituto direto. Para manter dados NRBF antigos, o NrbfDecoder do .NET 9 pode decodificar registros sem instanciar os tipos codificados. Valide a estrutura decodificada e mapeie somente valores esperados para DTOs da aplicação. Revise separadamente as orientações de migração de recursos, área de transferência e arrastar-e-soltar do WinForms/WPF.
Perguntas frequentes
A Microsoft recomenda migrar mesmo quando os dados parecem confiáveis, pois armazenamento, cache, arquivos, sincronização e serviços posteriores podem cruzar limites de confiança. Identifique quem pode gravar em cada origem e pare de usar BinaryFormatter em vez de depender dessa suposição.
No .NET 9, os tipos da API continuam, mas a implementação integrada sempre lança PlatformNotSupportedException, independentemente do antigo sinalizador de compatibilidade. Audite os usos e migre antes da atualização. Um pacote de compatibilidade sem suporte restaura a implementação vulnerável e não corrige a segurança.
Por padrão, Json.NET define TypeNameHandling como None, evitando que metadados do payload selecionem tipos CLR arbitrários. Não habilite outros valores para entrada não confiável. Se precisar de polimorfismo, use uma lista permitida controlada pela aplicação e siga a orientação da biblioteca. Consulte TypeNameHandling é seguro?
Fontes e referências
- Microsoft Learn — BinaryFormatter security guide
- Microsoft Learn — BinaryFormatter migration guide
- Microsoft Learn — Choose a BinaryFormatter replacement
- Microsoft Learn — Safely read NRBF payloads with NrbfDecoder
- Microsoft Learn — SYSLIB0011
- Microsoft Learn — ASP.NET ViewState MAC
- CWE-502 — Deserialization of Untrusted Data
- Is Json.NET TypeNameHandling safe?