Soluções

Cyber Security – Substituindo o BinaryFormatter no .NET

Cyber Security – BinaryFormatter: Um Risco à Segurança

O código fonte do .NET está em constante evolução e sua equipe de desenvolvimento está atenta as questões de Cyber Security, no entanto, classes legadas como o BinaryFormatter continuam a apresentar vulnerabilidades exploráveis por atacantes. Nesta análise, discutiremos a vulnerabilidade crítica associada ao BinaryFormatter registrada pelos códigos CVE-2023-32737, CWE-502, e CA2300 (você pode ler mais nos links), destacando o que são esses problemas, como eles impactam a segurança, e as melhores práticas para mitigá-los.

O que é o BinaryFormatter?

O BinaryFormatter é uma classe do .NET Framework utilizada para serializar e desserializar objetos em formato binário, facilitando o armazenamento ou a transferência de dados complexos. No entanto, devido à forma como o BinaryFormatter trata dados durante a desserialização, ele pode ser suscetível a ataques de desserialização inseguros, onde entradas maliciosas podem executar códigos arbitrários e comprometer a segurança da aplicação.

Cyber Security – Entendendo os Códigos de Vulnerabilidade

CVE-2023-32737: Código de Vulnerabilidade Comum

O CVE-2023-32737 é um identificador específico para uma vulnerabilidade do tipo “desserialização insegura” encontrada no BinaryFormatter. Ele indica que a manipulação de dados serializados possibilita a exploração da classe, permitindo que códigos realizem ações inesperadas e potencialmente maliciosas no ambiente de execução da aplicação.

CWE-502: Categoria de Fraquezas

O CWE-502 refere-se à categoria “Desserialização de Dados Não Confiáveis”. Essa classificação indica que uma vulnerabilidade ocorre quando dados maliciosos são desserializados, o que pode desencadear execuções de código indesejadas. Em outras palavras, o processamento de dados de entrada potencialmente perigosos pode ameaçar a segurança do sistema e comprometer sua integridade.

CA2300: Análise de Código para Segurança

O CA2300 recomenda evitar o processamento direto de dados não confiáveis, garantindo maior segurança no sistema. Esse aviso serve para alertar desenvolvedores durante o processo de construção do software, sinalizando o uso de práticas inseguras, como a desserialização direta de dados de fontes desconhecidas.

Impacto da Vulnerabilidade do BinaryFormatter

Ao utilizar o BinaryFormatter, aplicações correm o risco de receber objetos binários maliciosos que, durante a desserialização, podem executar código indesejado. Essa vulnerabilidade representa uma séria ameaça, pois permite a elevação de privilégios ou a execução de comandos remotamente, comprometendo a integridade do sistema.

Por ser uma biblioteca amplamente utilizada e inclusa no .NET Framework (não confundir com .NET Core, onde o uso do BinaryFormatter já é desaconselhado e possui suporte limitado), muitos sistemas podem ser alvos potenciais, especialmente os que interagem com dados de fontes externas.

Cyber Security – Quatro formas de mitigar o problema do BinaryFormatter

1. Substituindo o BinaryFormatter

  • A Microsoft já recomenda que o BinaryFormatter seja evitado em novos projetos, incentivando o uso de alternativas mais seguras, como o System.Text.Json, XmlSerializer, ou DataContractSerializer.

2. Verificar a Origem dos Dados

  • Garanta que dados serializados são provenientes de fontes confiáveis. Mesmo ao utilizar métodos alternativos de serialização, é importante controlar e garantir a confiabilidade da origem dos dados.

3. Cyber Security – Atualizar o .NET e Aplicar Patches de Segurança

  • A Microsoft lança periodicamente atualizações e patches para corrigir vulnerabilidades. Assegure-se de que o ambiente de desenvolvimento e os aplicativos estejam com as versões mais recentes do .NET Framework.

4. Realizar Análise Estática do Código

  • Ferramentas de análise estática, como o Code Analysis for .NET (que fornece o alerta CA2300), podem identificar o uso de BinaryFormatter e sugerir mudanças antes da implantação da aplicação.

Alternativas Seguras para Serialização

Como parte das melhores práticas, os desenvolvedores podem considerar o uso de serializadores seguros e específicos para os dados e cenários em questão. Algumas das alternativas recomendadas incluem:

  • System.Text.Json: Uma alternativa leve e segura para a serialização JSON.
  • DataContractSerializer: Indicado para cenários de comunicação entre serviços, pois oferece mais controle sobre o que é serializado.
  • Protobuf: Uma alternativa altamente eficiente e segura, principalmente para comunicação entre microserviços.
  • NrbfDecoder: Uma alternativa voltada para a leitura e interpretação de objetos binários que mantém compatibilidade com o BinaryFormatter. É usada para decodificar o formato NRBF (.NET Remoting Binary Format), que permite manipular dados binários sem os riscos de execução de código presentes no BinaryFormatter. Embora não seja uma substituição direta, o NrbfDecoder pode ajudar a migrar dados legados ou analisar binários com segurança. Saiba mais sobre o NrbfDecoder no site da Microsoft.

Cyber Security – Substituindo o BinaryFormatter com o NrbfDecoder

Imagine o cenário onde recebemos via API, dados formatados usando o BinaryFormatter, ou seja, não temos domínio sobre o client mas apenas da API que deserializa esses dados tambem usando o BinaryFormatter.

Este caso categoriza o problema de segurança pois podemos receber um código malicioso entre esses dados. Como podemos resolver nosso lado sem quebrar o contrato com os consumidores de nossas APIs?

Uma opção é usar o NrbfDecoder, uma biblioteca disponível no NuGet. Na data de escrita deste artigo, ela ainda permanece em Release Candidate, embora a Microsoft já a considere em “produção”. Isso ocorre porque sua API ainda deve passar por uma grande atualização.

Vamos explorar abaixo uma solução de desserialização com o NrbfDecoder mencionado anteriormente.

Considere que a classe abaixo foi serializada com BinaryFormatter e recebemos uma MemoryStream contendo esta classe.

public class Employee
{
 public int Id { get; set; }
 public List<string> Roles { get; set; }
}

Vamos ao codigo que desserializa:

...
// Valida se a MemoryStream pode ser desserializada
if (NrbfDecoder.StartsWithPayloadHeader(memoryStream))
{
 memoryStream.Position = 0;
 // Decodifica a instancia de uma classe que não seja um Array ou tipo primitivo
 ClassRecord decodedClass = NrbfDecoder.DecodeClassRecord(memoryStream);
 
 // Iterando sobre as propriedades para fazer bind pelo nome
 foreach (var memberName in decodedClass.MemberNames)
 {
  if (memberName.Equals(nameof(employee.Id))
  {
   // Lidando com tipos primitivos
   employee.Id = decodedClass.GetInt32(memberName);
  }
  
  if (memberName.Equals(nameof(employee.Roles))
  {
   var complexDecoded = decodedClass.GetClassRecord(memberName);
   
   // Identifico o tipo para trata-lo corretamente
   if (complexDecoded.TypeName.FullName.Contains("List[[System.String]]"))
   {
    var listDecoded = complexDecoded.GetArrayRecord("_items")
                    .GetArray(expectedArrayType: typeof(string));
    
    foreach (var item in listDecoded)
    {
     // Se for tipo primitivo
     if (item is not ClassRecord)
     {
      employee.Roles.Add(item);
     }
     
     // Caso não seja tipo primitivo aqui seguimos decodificando as
     // classes ou arrays conforme fizemos anteriormente.
    }
   }
  }
 }
 
 // Ao final temos uma instancia da classe Employee desserializada
 

Conclusão

Embora o BinaryFormatter seja uma ferramenta poderosa no .NET, ele se tornou uma fonte de risco devido à sua suscetibilidade à desserialização insegura, dessa forma a vulnerabilidade identificada pelo CVE-2023-32737 e categorizada em CWE-502 destaca a necessidade de adotar práticas seguras de serialização e controle de dados. Por isso, a Microsoft e a comunidade .NET recomendam substituir o BinaryFormatter por métodos de serialização mais seguros, protegendo assim as aplicações e prevenindo que explorações comprometam a integridade do sistema.

Vinicius Sodré

Formado em Ciência da Computação pela Unicarioca, desenvolvedor de software com 15 anos de experiência em grandes empresas nacionais e multinacionais. Vinicius está à frente deste blog, feito de desenvolvedor para desenvolvedores de iniciantes a experientes.

Compartilhar
Publicado por:
Vinicius Sodré

Posts Recentes

Desenvolvimento de APIs Python: Frameworks e Melhores Práticas

O Desenvolvimento de APIs Python tornou-se uma habilidade fundamental para programadores modernos. Com sua sintaxe clara e…

7 meses atrás

Segurança em Aplicações Python

A segurança em aplicações Python é uma grande preocupação para desenvolvedores. Com o aumento de…

8 meses atrás

Python para Análise de Dados em Tempo Real: Guia Completo

A análise de dados em tempo real tornou-se um componente crítico para empresas que precisam…

9 meses atrás

Frameworks Python para Web: Guia Completo

O desenvolvimento web evoluiu significativamente nos últimos anos, e os frameworks Python estão na vanguarda…

9 meses atrás

Python para IA: Domine o Caminho para a Inteligência Artificial

A inteligência artificial está revolucionando todos os setores da sociedade, desde aplicações empresariais até soluções…

9 meses atrás

Tuples e Sets em Python: quando usar cada um – Aula 11

Nesta aula do minicurso de Python, quero abordar dois tipos de coleção que são usadas…

10 meses atrás

Este blog utiliza cookies. Se você continuar assumiremos que você está satisfeito com ele.

Leia Mais...