CA2322: Garantir que o JavaScriptSerializer não seja inicializado com SimpleTypeResolver antes de desserializar
Property | Valor |
---|---|
ID da regra | CA2322 |
Título | Garantir que o JavaScriptSerializer não seja inicializado com SimpleTypeResolver antes de desserializar |
Categoria | Segurança |
Correção interruptiva ou sem interrupção | Sem interrupção |
Habilitado por padrão no .NET 8 | Não |
Causa
Um método de desserialização System.Web.Script.Serialization.JavaScriptSerializer foi chamado ou referenciado e o JavaScriptSerializer pode ter sido inicializado com um System.Web.Script.Serialization.SimpleTypeResolver.
Por padrão, essa regra analisa toda a base de código, mas isso é configurável.
Descrição da regra
Desserializadores não seguros são vulneráveis ao desserializar dados não confiáveis. Um invasor pode modificar os dados serializados visando incluir tipos inesperados para injetar objetos com efeitos colaterais mal-intencionados. Um ataque contra um desserializador não seguro poderia, por exemplo, executar comandos no sistema operacional subjacente, realizar comunicações pela rede ou excluir arquivos.
Essa regra localiza chamadas de método de desserialização ou referências System.Web.Script.Serialization.JavaScriptSerializer, quando o JavaScriptSerializer pode ter sido inicializado com um System.Web.Script.Serialization.SimpleTypeResolver.
Como corrigir violações
- Verifique se os objetos JavaScriptTypeResolver não são inicializados com um System.Web.Script.Serialization.SimpleTypeResolver.
- Se seu código precisar ler dados serializados usando um SimpleTypeResolver, restrinja tipos desserializados a uma lista esperada implementando um JavaScriptTypeResolver personalizado.
- Torne os dados serializados à prova de adulteração. Após a serialização, assine criptograficamente os dados serializados. Antes da desserialização, valide a assinatura criptográfica. Proteja a chave criptográfica para impedir que ela seja divulgada e projete rotações de chave.
Quando suprimir avisos
É seguro suprimir um aviso dessa regra se:
- Você souber que a entrada é confiável. Considere que o limite de confiança do seu aplicativo e os fluxos de dados podem ser alterados ao longo do tempo.
- Você tiver tomado uma das precauções descritas em Como corrigir violações.
Suprimir um aviso
Para suprimir apenas uma violação, adicione diretivas de pré-processador ao arquivo de origem a fim de desabilitar e, em seguida, reabilitar a regra.
#pragma warning disable CA2322
// The code that's violating the rule is on this line.
#pragma warning restore CA2322
Para desabilitar a regra em um arquivo, uma pasta ou um projeto, defina a severidade como none
no arquivo de configuração.
[*.{cs,vb}]
dotnet_diagnostic.CA2322.severity = none
Para obter mais informações, confira Como suprimir avisos de análise de código.
Configurar código para analisar
Use as opções a seguir para configurar em quais partes da base de código essa regra deve ser executada.
Você pode configurar essas opções apenas para essa regra, para todas as regras às quais ela se aplica ou para todas as regras nessa categoria (Segurança) às quais ela se aplica. Para saber mais, confira Opções de configuração de regra de qualidade de código.
Excluir símbolos específicos
Você pode excluir da análise símbolos específicos, como tipos e métodos. Por exemplo, para especificar que a regra não deve ser executada em nenhum código dentro de tipos nomeados MyType
, adicione o seguinte par chave-valor a um arquivo .editorconfig no seu projeto:
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType
Formatos de nome de símbolo permitidos no valor da opção (separados por |
):
- Somente nome do símbolo (inclui todos os símbolos com o nome, independentemente do tipo ou namespace que contém).
- Nomes totalmente qualificados no formato de ID de documentação do símbolo. Cada nome de símbolo requer um prefixo do tipo símbolo, como
M:
para métodos,T:
para tipos eN:
para namespaces. .ctor
para construtores e.cctor
para construtores estáticos.
Exemplos:
Valor de Opção | Resumo |
---|---|
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType |
Corresponde a todos os símbolos nomeados MyType . |
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 |
Corresponde a todos os símbolos nomeados MyType1 ou MyType2 . |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) |
Corresponde ao método MyMethod específico com a assinatura totalmente qualificada especificada. |
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) |
Corresponde aos métodos MyMethod1 e MyMethod2 específico com as assinaturas respectivas totalmente qualificadas. |
Excluir tipos específicos e seus tipos derivados
Você pode excluir tipos específicos e seus tipos derivados da análise. Por exemplo, para especificar que a regra não deve ser executada em nenhum método dentro de tipos nomeados MyType
e seus tipos derivados, adicione o seguinte par chave-valor a um arquivo .editorconfig no seu projeto:
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType
Formatos de nome de símbolo permitidos no valor da opção (separados por |
):
- Somente nome do tipo (inclui todos os tipos com o nome, independentemente do tipo ou namespace que contém).
- Nomes totalmente qualificados no formato de ID de documentação do símbolo, com um prefixo opcional
T:
.
Exemplos:
Valor de Opção | Resumo |
---|---|
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType |
Corresponde a todos os tipos nomeados MyType e todos os seus tipos derivados. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 |
Corresponde a todos os tipos nomeados MyType1 ou MyType2 e todos os seus tipos derivados. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType |
Corresponde a um tipo MyType específico com determinado nome totalmente qualificado e todos os seus tipos derivados. |
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 |
Corresponde a tipos MyType1 e MyType2 específicos com os respectivos nomes totalmente qualificados e todos os seus tipos derivados. |
Exemplos de pseudocódigo
Violação 1
using System.Web.Script.Serialization;
public class ExampleClass
{
public JavaScriptSerializer Serializer { get; set; }
public T Deserialize<T>(string str)
{
return this.Serializer.Deserialize<T>(str);
}
}
Imports System.Web.Script.Serialization
Public Class ExampleClass
Public Property Serializer As JavaScriptSerializer
Public Function Deserialize(Of T)(str As String) As T
Return Me.Serializer.Deserialize(Of T)(str)
End Function
End Class
Solução 1
using System.Web.Script.Serialization;
public class ExampleClass
{
public T Deserialize<T>(string str)
{
JavaScriptSerializer s = new JavaScriptSerializer();
return s.Deserialize<T>(str);
}
}
Imports System.Web.Script.Serialization
Public Class ExampleClass
Public Function Deserialize(Of T)(str As String) As T
Dim s As JavaScriptSerializer = New JavaScriptSerializer()
Return s.Deserialize(Of T)(str)
End Function
End Class
Violação 2
using System.Web.Script.Serialization;
public class BookRecord
{
public string Title { get; set; }
public string Author { get; set; }
public int PageCount { get; set; }
public AisleLocation Location { get; set; }
}
public class AisleLocation
{
public char Aisle { get; set; }
public byte Shelf { get; set; }
}
public class ExampleClass
{
public JavaScriptSerializer Serializer { get; set; }
public BookRecord DeserializeBookRecord(string s)
{
return this.Serializer.Deserialize<BookRecord>(s);
}
}
Imports System.Web.Script.Serialization
Public Class BookRecord
Public Property Title As String
Public Property Author As String
Public Property Location As AisleLocation
End Class
Public Class AisleLocation
Public Property Aisle As Char
Public Property Shelf As Byte
End Class
Public Class ExampleClass
Public Property Serializer As JavaScriptSerializer
Public Function DeserializeBookRecord(str As String) As BookRecord
Return Me.Serializer.Deserialize(Of BookRecord)(str)
End Function
End Class
Solução 2
using System;
using System.Web.Script.Serialization;
public class BookRecordTypeResolver : JavaScriptTypeResolver
{
// For compatibility with data serialized with a JavaScriptSerializer initialized with SimpleTypeResolver.
private static readonly SimpleTypeResolver Simple = new SimpleTypeResolver();
public override Type ResolveType(string id)
{
// One way to discover expected types is through testing deserialization
// of **valid** data and logging the types used.
////Console.WriteLine($"ResolveType('{id}')");
if (id == typeof(BookRecord).AssemblyQualifiedName || id == typeof(AisleLocation).AssemblyQualifiedName)
{
return Simple.ResolveType(id);
}
else
{
throw new ArgumentException("Unexpected type ID", nameof(id));
}
}
public override string ResolveTypeId(Type type)
{
return Simple.ResolveTypeId(type);
}
}
public class BookRecord
{
public string Title { get; set; }
public string Author { get; set; }
public int PageCount { get; set; }
public AisleLocation Location { get; set; }
}
public class AisleLocation
{
public char Aisle { get; set; }
public byte Shelf { get; set; }
}
public class ExampleClass
{
public BookRecord DeserializeBookRecord(string s)
{
JavaScriptSerializer serializer = new JavaScriptSerializer(new BookRecordTypeResolver());
return serializer.Deserialize<BookRecord>(s);
}
}
Imports System
Imports System.Web.Script.Serialization
Public Class BookRecordTypeResolver
Inherits JavaScriptTypeResolver
' For compatibility with data serialized with a JavaScriptSerializer initialized with SimpleTypeResolver.
Private Dim Simple As SimpleTypeResolver = New SimpleTypeResolver()
Public Overrides Function ResolveType(id As String) As Type
' One way to discover expected types is through testing deserialization
' of **valid** data and logging the types used.
''Console.WriteLine($"ResolveType('{id}')")
If id = GetType(BookRecord).AssemblyQualifiedName Or id = GetType(AisleLocation).AssemblyQualifiedName Then
Return Simple.ResolveType(id)
Else
Throw New ArgumentException("Unexpected type", NameOf(id))
End If
End Function
Public Overrides Function ResolveTypeId(type As Type) As String
Return Simple.ResolveTypeId(type)
End Function
End Class
Public Class BookRecord
Public Property Title As String
Public Property Author As String
Public Property Location As AisleLocation
End Class
Public Class AisleLocation
Public Property Aisle As Char
Public Property Shelf As Byte
End Class
Public Class ExampleClass
Public Function DeserializeBookRecord(str As String) As BookRecord
Dim serializer As JavaScriptSerializer = New JavaScriptSerializer(New BookRecordTypeResolver())
Return serializer.Deserialize(Of BookRecord)(str)
End Function
End Class
Regras relacionadas
CA2321: Não desserializar com JavaScriptSerializer usando um SimpleTypeResolver