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 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.
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.
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.
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.
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.
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:
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
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.
A inteligência artificial está revolucionando todos os setores da sociedade, desde aplicações empresariais até soluções…
Nesta aula do minicurso de Python, quero abordar dois tipos de coleção que são usadas…
Entre as estruturas de dados mais versáteis do Python, os dicionários se destacam. Eles nos…
Nesta nona aula do mini curso, quero falar sobre um dos tipos de dados mais…
Entender o escopo de variáveis em Python é essencial para evitar erros e criar programas…
As funções são um dos conceitos mais importantes em qualquer linguagem de programação, e no…
Este blog utiliza cookies. Se você continuar assumiremos que você está satisfeito com ele.
Leia Mais...