Diretrizes de segurança de DataSet e DataTable

Este artigo se aplica ao:

  • .NET Framework (todas as versões)
  • ASP.NET Core e posteriores
  • .NET 5 e posteriores

Os tipos DataSet e DataTable são componentes .NET herdados que permitem representar conjuntos de dados como objetos gerenciados. Esses componentes foram introduzidos no .NET Framework 1.0 como parte da infraestrutura de ADO.NET original. O objetivo era fornecer uma visão gerenciada de um conjunto de dados relacional, abstraindo se a fonte subjacente dos dados era XML, SQL ou outra tecnologia.

Para obter mais informações sobre ADO.NET, incluindo paradigmas de exibição de dados mais modernos, confira a documentação ADO.NET.

Restrições padrão ao desserializar um DataSet ou DataTable de XML

Em todas as versões com suporte do .NET Framework, do .NET Core e do .NET, DataSet e DataTable colocam as seguintes restrições sobre quais tipos de objetos podem estar presentes nos dados desserializados. Por padrão, essa lista é restrita a:

  • Primitivos e equivalentes primitivos: bool, char, sbyte, byte, short, ushort, int, uint, long, ulong, float, double, decimal, DateTime, DateTimeOffset, TimeSpan, string, Guid, SqlBinary, SqlBoolean, SqlByte, SqlBytes, SqlChars, SqlDateTime, SqlDecimal, SqlDouble, SqlGuid, SqlInt16, SqlInt32, SqlInt64, SqlMoney, SqlSingle e SqlString.
  • Não primitivos comumente usados: Type, Uri e BigInteger.
  • Tipos System.Drawing comumente usados: Color, Point, PointF, Rectangle, RectangleF, Size e SizeF.
  • Tipos Enum.
  • Matrizes e listas dos tipos acima.

Se os dados XML de entrada contiverem um objeto cujo tipo não está nesta lista:

  • Uma exceção é gerada com a mensagem a seguir e o rastreamento de pilha. Mensagem de erro: System.InvalidOperationException: Type '<Type Name>, Version=<n.n.n.n>, Culture=<culture>, PublicKeyToken=<token value>' não é permitido aqui. Rastreamento de pilha: em System.Data.TypeLimiter.EnsureTypeIsAllowed(Type type, TypeLimiter capturedLimiter) em System.Data.DataColumn.UpdateColumnType(Type type, StorageType typeCode) em System.Data.DataColumn.set_DataType(Type value)

  • A operação de desserialização falha.

Ao carregar XML em uma instância DataSet ou DataTable, as definições de coluna existentes também são levadas em conta. Se a tabela já contiver uma definição de coluna de um tipo personalizado, esse tipo será adicionado temporariamente à lista de permissões durante a operação de desserialização XML.

Observação

Depois de adicionar colunas a um DataTable, ReadXml não lerá o esquema do XML e, se o esquema não corresponder, ele também não será lido nos registros. Por isso, você precisará adicionar todas as colunas por conta própria para usar esse método.

XmlReader xmlReader = GetXmlReader();

// Assume the XML blob contains data for type MyCustomClass.
// The following call to ReadXml fails because MyCustomClass isn't in the allowed types list.

DataTable table = new DataTable("MyDataTable");
table.ReadXml(xmlReader);

// However, the following call to ReadXml succeeds, since the DataTable instance
// already defines a column of type MyCustomClass.

DataTable table = new DataTable("MyDataTable");
table.Columns.Add("MyColumn", typeof(MyCustomClass));
table.ReadXml(xmlReader); // this call will succeed

As restrições de tipo de objeto também se aplicam ao usar XmlSerializer para desserializar uma instância de DataSet ou DataTable. No entanto, elas podem não se aplicar ao usar BinaryFormatter para desserializar uma instância de DataSet ou DataTable.

As restrições de tipo de objeto não se aplicam ao usar DataAdapter.Fill, como quando uma instância DataTable é preenchida diretamente de um banco de dados sem usar as APIs de desserialização XML.

Estender a lista de tipos permitidos

Um aplicativo pode estender a lista de tipos permitidos para incluir tipos personalizados, além dos tipos internos listados acima. Ao estender a lista de tipos permitidos, a alteração afetará todas as instâncias DataSet e DataTable no aplicativo. Os tipos não podem ser removidos da lista de tipos permitidos internos.

Estender pela configuração (.NET Framework 4.0 e posteriores)

App.config pode ser usado para estender a lista de tipos permitidos. Para estender a lista de tipos permitidos:

  • Use o elemento <configSections> para adicionar uma referência à seção de configuração System.Data.
  • Use <system.data.dataset.serialization>/<allowedTypes> para especificar tipos adicionais.

Cada elemento <add> precisa especificar apenas um tipo usando seu nome de tipo qualificado de assembly. Para adicionar tipos adicionais à lista de tipos permitidos, use vários elementos <add>.

O exemplo a seguir mostra a extensão da lista de tipos permitidos adicionando o tipo Fabrikam.CustomType personalizado.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="system.data.dataset.serialization" type="System.Data.SerializationSettingsSectionGroup, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="allowedTypes" type="System.Data.AllowedTypesSectionHandler, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </sectionGroup>
  </configSections>
  <system.data.dataset.serialization>
    <allowedTypes>
      <!-- <add type="assembly qualified type name" /> -->
      <add type="Fabrikam.CustomType, Fabrikam, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2b3831f2f2b744f7" />
      <!-- additional <add /> elements as needed -->
    </allowedTypes>
  </system.data.dataset.serialization>
</configuration>

Para recuperar o nome qualificado do assembly por um tipo, use a propriedade Type.AssemblyQualifiedName, conforme demonstrado no código a seguir.

string assemblyQualifiedName = typeof(Fabrikam.CustomType).AssemblyQualifiedName;

Estender pela configuração (NET Framework 2.0 - 3.5)

Se o aplicativo for direcionado ao .NET Framework 2.0 ou 3.5, você ainda poderá usar o mecanismo App.config acima para estender a lista de tipos permitidos. No entanto, seu elemento <configSections> será ligeiramente diferente, conforme mostrado no seguinte código:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <!-- The below <sectionGroup> and <section> are specific to .NET Framework 2.0 and 3.5. -->
    <sectionGroup name="system.data.dataset.serialization" type="System.Data.SerializationSettingsSectionGroup, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="allowedTypes" type="System.Data.AllowedTypesSectionHandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </sectionGroup>
  </configSections>
  <system.data.dataset.serialization>
    <allowedTypes>
      <!-- <add /> elements, as demonstrated in the .NET Framework 4.0 - 4.8 sample code above. -->
    </allowedTypes>
  </system.data.dataset.serialization>
</configuration>

Estender programaticamente (.NET Framework, .NET Core, .NET 5+)

A lista de tipos permitidos também pode ser estendida programaticamente usando AppDomain.SetData com a conhecida chave System.Data.DataSetDefaultAllowedTypes, conforme mostrado no código a seguir.

Type[] extraAllowedTypes = new Type[]
{
    typeof(Fabrikam.CustomType),
    typeof(Contoso.AdditionalCustomType)
};

AppDomain.CurrentDomain.SetData("System.Data.DataSetDefaultAllowedTypes", extraAllowedTypes);

Se estiver usando o mecanismo de extensão, o valor associado à chave System.Data.DataSetDefaultAllowedTypes deverá ser do tipo Type[].

No .NET Framework, a lista de tipos permitidos pode ser estendida com App.config e AppDomain.SetData. Nesse caso, DataSet e DataTable permitirão que um objeto seja desserializado como parte dos dados se seu tipo estiver presente em qualquer lista.

Executar um aplicativo no modo de auditoria (.NET Framework)

No.NET Framework, DataSet e DataTable fornecem uma funcionalidade de modo de auditoria. Quando o modo de auditoria estiver habilitado, DataSet e DataTable comparam os tipos de objetos de entrada com a lista de tipos permitidos. No entanto, se um objeto cujo tipo não é permitido for visto, uma exceção não será gerada. Em vez disso, DataSet e DataTable notificam as instâncias TraceListener anexadas de que um tipo suspeito está presente, permitindo que TraceListener registre essas informações em log. Nenhuma exceção é gerada e a operação de desserialização continua.

Aviso

Executar um aplicativo no "modo de auditoria" deve ser apenas uma medida temporária usada para teste. Quando o modo de auditoria está habilitado, DataSet e DataTable não impõem restrições de tipo, o que pode introduzir uma falha de segurança dentro de seu aplicativo. Para obter mais informações, consulte as seções intituladas Removendo todas as restrições de tipo e Segurança em relação à entrada não confiável.

O modo de auditoria pode ser habilitado por meio de App.config:

  • Consulte a seção Estender por meio da configuração neste documento para obter informações sobre o valor apropriado a ser colocado para o elemento <configSections>.
  • Use <allowedTypes auditOnly="true"> para habilitar o modo de auditoria, conforme mostrado na marcação a seguir.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <!-- See the section of this document titled "Extending through configuration" for the appropriate
         <sectionGroup> and <section> elements to put here, depending on whether you're running .NET
         Framework 2.0 - 3.5 or 4.0 - 4.8. -->
  </configSections>
  <system.data.dataset.serialization>
    <allowedTypes auditOnly="true"> <!-- setting auditOnly="true" enables audit mode -->
      <!-- Optional <add /> elements as needed. -->
    </allowedTypes>
  </system.data.dataset.serialization>
</configuration>

Depois que o modo de auditoria estiver habilitado, você poderá usar App.config para conectar o TraceListener de sua preferência ao TraceSource. integrado ao DataSet. O nome da fonte de rastreamento integrada é System.Data.DataSet. O exemplo a seguir demonstra a gravação de eventos de rastreamento no console e em um arquivo de log no disco.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <sources>
      <source name="System.Data.DataSet"
              switchType="System.Diagnostics.SourceSwitch"
              switchValue="Warning">
        <listeners>
          <!-- write to the console -->
          <add name="console"
               type="System.Diagnostics.ConsoleTraceListener" />
          <!-- *and* write to a log file on disk -->
          <add name="filelog"
               type="System.Diagnostics.TextWriterTraceListener"
               initializeData="c:\logs\mylog.txt" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
</configuration>

Para mais informações sobre TraceSource e TraceListener, confira o documento Como usar TraceSource e filtros com ouvintes de rastreamento.

Observação

A execução de um aplicativo no modo de auditoria não está disponível no .NET Core ou no .NET 5 e posteriores.

Remover todas as restrições de tipo

Se um aplicativo precisar remover todas as restrições de limitação de tipo DataSet e DataTable:

  • Há várias opções para suprimir restrições de limitação de tipo.
  • As opções disponíveis dependem da estrutura que o aplicativo visa.

Aviso

Remover todas as restrições de tipo pode introduzir uma falha de segurança dentro do aplicativo. Ao usar esse mecanismo, verifique se o aplicativo não usa DataSet ou DataTable para ler entradas não confiáveis. Para obter mais informações, consulte CVE-2020-1147 e a seção a seguir intitulada Segurança em relação à entrada não confiável.

Por meio da configuração do AppContext (.NET Framework 4.6 e posterior, .NET Core 2.1 e posterior, .NET 5 e posterior)

O botão AppContext, Switch.System.Data.AllowArbitraryDataSetTypeInstantiation, quando definido como true, remove todas as restrições de limitação de tipo de DataSet e DataTable.

No .NET Framework, essa opção pode ser habilitada por meio do App.config, conforme mostrado na seguinte configuração:

<configuration>
   <runtime>
      <!-- Warning: setting the following switch can introduce a security problem. -->
      <AppContextSwitchOverrides value="Switch.System.Data.AllowArbitraryDataSetTypeInstantiation=true" />
   </runtime>
</configuration>

No ASP.NET, o elemento <AppContextSwitchOverrides> não está disponível. Em vez disso, a botão pode ser habilitada por meio de Web.config, conforme mostrado na seguinte configuração:

<configuration>
    <appSettings>
        <!-- Warning: setting the following switch can introduce a security problem. -->
        <add key="AppContext.SetSwitch:Switch.System.Data.AllowArbitraryDataSetTypeInstantiation" value="true" />
    </appSettings>
</configuration>

Para obter mais informações, confira o elemento <AppContextSwitchOverrides>.

No .NET Core, .NET 5 e ASP.NET Core, essa configuração é controlada por runtimeconfig.json, conforme mostrado no seguinte JSON:

{
  "runtimeOptions": {
    "configProperties": {
      "Switch.System.Data.AllowArbitraryDataSetTypeInstantiation": true
    }
  }
}

Para obter mais informações, consulte Definições de configuração de runtime do .NET.

AllowArbitraryDataSetTypeInstantiation também pode ser definido programaticamente por meio de AppContext.SetSwitch em vez de usar um arquivo de configuração, conforme mostrado no seguinte código:

// Warning: setting the following switch can introduce a security problem.
AppContext.SetSwitch("Switch.System.Data.AllowArbitraryDataSetTypeInstantiation", true);

Se você escolher a abordagem programática anterior, a chamada para AppContext.SetSwitch deve ocorrer no início da inicialização de aplicativos.

Por meio do registro em todo o computador (.NET Framework 2.0 – 4.x)

Se AppContext não estiver disponível, as verificações de limitação de tipo poderão ser desabilitadas com o registro do Windows:

  • Um administrador precisa configurar o registro.
  • O uso do registro é uma alteração em todo o computador e afetará todos os aplicativos em execução no computador.
Tipo Valor
Chave do Registro HKLM\SOFTWARE\Microsoft\.NETFramework\AppContext
Nome do valor Switch.System.Data.AllowArbitraryDataSetTypeInstantiation
Tipo de valor REG_SZ
Dados do valor true

Em um sistema operacional de 64 bits, esse valor precisa ser adicionado tanto para a chave de 64 bits (mostrada acima) quanto para a chave de 32 bits. A chave de 32 bits está localizada em HKLM\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\AppContext.

Para obter mais informações sobre como usar o registro para configurar AppContext, consulte "AppContext para clientes de biblioteca".

Segurança em relação à entrada não confiável

Enquanto DataSet e DataTable imponham limitações padrão aos tipos que têm permissão para estar presentes durante a desserialização de conteúdo XML, em geral, DataSet e DataTable não são seguros quando preenchidos com entrada não confiável. A seguir, temos uma lista não completa de como uma instância DataSet ou DataTable pode ler entradas não confiáveis.

  • Um DataAdapter referencia um banco de dados e o método DataAdapter.Fill é usado para preencher um DataSet com o conteúdo de uma consulta de banco de dados.
  • O método DataSet.ReadXml ou DataTable.ReadXml é usado para ler um arquivo XML que contém informações de coluna e linha.
  • Uma instância DataSet ou DataTable é serializada como parte de serviços Web ASP.NET (SOAP) ou ponto de extremidade do WCF.
  • Um serializador como XmlSerializer é usado para desserializar uma instância DataSet ou DataTable de um fluxo de XML.
  • Um serializador como JsonConvert é usado para desserializar uma instância DataSet ou DataTable de um fluxo JSON. JsonConvert é um método na popular na biblioteca Newtonsoft.Json de terceiros.
  • Um serializador como BinaryFormatter é usado para desserializar uma instância DataSet ou DataTable de um fluxo de byte bruto.

Este documento discute considerações de segurança para os cenários anteriores.

Usar DataAdapter.Fill para preencher um DataSet de uma fonte de dados não confiável

Uma instância DataSet pode ser preenchida de um DataAdapter usando o método DataAdapter.Fill, conforme mostrado no exemplo a seguir.

// Assumes that connection is a valid SqlConnection object.
string queryString =
  "SELECT CustomerID, CompanyName FROM dbo.Customers";
SqlDataAdapter adapter = new SqlDataAdapter(queryString, connection);

DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");

(O exemplo de código acima faz parte de uma amostra maior encontrada em Populando um Conjunto de Dados de um DataAdapter.)

A maioria dos aplicativos pode simplificar e assumir que sua camada de banco de dados é confiável. No entanto, se você tem o hábito de modelar ameaças nos seus aplicativos, seu modelo de ameaça poderá considerar que há um limite de confiança entre o aplicativo (cliente) e a camada de banco de dados (servidor). Usar a autenticação mútua ou a autenticação do AAD entre o cliente e o servidor é uma maneira de ajudar a resolver os riscos associados a isso. O restante desta seção discute o possível resultado de um cliente ao se conectar a um servidor não confiável.

As consequências de apontar um DataAdapter em uma fonte de dados não confiável dependem da implementação do próprio DataAdapter.

SqlDataAdapter

Para o tipo integrado SqlDataAdapter, fazer referência a uma fonte de dados não confiável pode resultar em um ataque de DoS (negação de serviço). O ataque do DoS pode fazer com que o aplicativo não responda ou falhe. Se um invasor puder plantar uma DLL ao lado do aplicativo, ele também poderá obter a execução do código local.

Outros tipos de DataAdapter

Implementações DataAdapter de terceiros precisam fazer suas próprias avaliações sobre quais garantias de segurança elas fornecem em face de entradas não confiáveis. O .NET não pode fazer garantias de segurança em relação a essas implementações.

DataSet.ReadXml e DataTable.ReadXml

Os métodos DataSet.ReadXml e DataTable.ReadXml não são seguros quando usados com entrada não confiável. Recomendamos fortemente que os consumidores considerem usar uma das alternativas descritas posteriormente neste artigo.

As implementações de DataSet.ReadXml e DataTable.ReadXml foram criadas originalmente antes das vulnerabilidades de serialização serem uma categoria de ameaça bem compreendida. Como resultado, o código não segue as melhores práticas de segurança atuais. Essas APIs podem ser usadas como vetores para invasores executarem ataques do DoS em aplicativos Web. Esses ataques podem fazer com que o serviço Web deixe de responder ou resultar em um encerramento inesperado do processo. A estrutura não fornece mitigações para essas categorias de ataque e o .NET considera esse comportamento "por design".

O .NET lançou atualizações de segurança para atenuar alguns problemas, como divulgação de informações ou execução remota de código no DataSet.ReadXml e DataTable.ReadXml. As atualizações de segurança do .NET podem não fornecer proteção completa contra essas categorias de ameaças. Os consumidores devem avaliar seus cenários individuais e considerar sua potencial exposição a esses riscos.

Os consumidores devem estar cientes de que as atualizações de segurança para essas APIs podem afetar a compatibilidade do aplicativo em algumas situações. Além disso, a possibilidade de que seja descoberta uma nova vulnerabilidade nessas APIs para a qual o .NET não consiga publicar de modo prático uma atualização de segurança.

Recomendamos que os consumidores dessas APIs:

  • Considerem usar uma das alternativas descritas posteriormente neste documento.
  • Executem avaliações de risco individuais em seus aplicativos.

É responsabilidade exclusiva do consumidor determinar se ele deve utilizar essas APIs. Os consumidores devem avaliar riscos de segurança, técnicos e legais, incluindo requisitos regulatórios, que possam acompanhar o uso dessas APIs.

DataSet e DataTable por meio de serviços Web ASP.NET ou WCF

É possível aceitar uma instância DataSet e DataTable em um serviço Web ASP.NET (SOAP), conforme demonstrado no seguinte código:

using System.Data;
using System.Web.Services;

[WebService(Namespace = "http://contoso.com/")]
public class MyService : WebService
{
    [WebMethod]
    public string MyWebMethod(DataTable dataTable)
    {
        /* Web method implementation. */
    }
}

Uma variação sobre isso não é aceitar DataSet ou DataTable diretamente como um parâmetro, mas sim aceitá-lo como parte do grafo geral do objeto serializado SOAP, conforme mostrado no seguinte código:

using System.Data;
using System.Web.Services;

[WebService(Namespace = "http://contoso.com/")]
public class MyService : WebService
{
    [WebMethod]
    public string MyWebMethod(MyClass data)
    {
        /* Web method implementation. */
    }
}

public class MyClass
{
    // Property of type DataTable, automatically serialized and
    // deserialized as part of the overall MyClass payload.
    public DataTable MyDataTable { get; set; }
}

Ou, usando o WCF em vez de serviços Web ASP.NET:

using System.Data;
using System.ServiceModel;

[ServiceContract(Namespace = "http://contoso.com/")]
public interface IMyContract
{
    [OperationContract]
    string MyMethod(DataTable dataTable);
    [OperationContract]
    string MyOtherMethod(MyClass data);
}

public class MyClass
{
    // Property of type DataTable, automatically serialized and
    // deserialized as part of the overall MyClass payload.
    public DataTable MyDataTable { get; set; }
}

Em todos esses casos, o modelo de ameaça e as garantias de segurança são iguais à seção DataSet.ReadXml e DataTable.ReadXml.

Desserializar um DataSet ou DataTable via XmlSerializer

Os desenvolvedores podem usar XmlSerializer para desserializar instâncias DataSet e DataTable, conforme mostrado no seguinte código:

using System.Data;
using System.IO;
using System.Xml.Serialization;

public DataSet PerformDeserialization1(Stream stream) {
    XmlSerializer serializer = new XmlSerializer(typeof(DataSet));
    return (DataSet)serializer.Deserialize(stream);
}

public MyClass PerformDeserialization2(Stream stream) {
    XmlSerializer serializer = new XmlSerializer(typeof(MyClass));
    return (MyClass)serializer.Deserialize(stream);
}

public class MyClass
{
    // Property of type DataTable, automatically serialized and
    // deserialized as part of the overall MyClass payload.
    public DataTable MyDataTable { get; set; }
}

Nesses casos, o modelo de ameaça e as garantias de segurança são iguais à seção DataSet.ReadXml e DataTable.ReadXml

Desserializar um DataSet ou DataTable via JsonConvert

A popular biblioteca Newtonsoft de terceiros Json.NET pode ser usada para desserializar as instâncias DataSet e DataTable, conforme mostrado no código a seguir:

using System.Data;
using Newtonsoft.Json;

public DataSet PerformDeserialization1(string json) {
    return JsonConvert.DeserializeObject<DataSet>(data);
}

public MyClass PerformDeserialization2(string json) {
    return JsonConvert.DeserializeObject<MyClass>(data);
}

public class MyClass
{
    // Property of type DataTable, automatically serialized and
    // deserialized as part of the overall MyClass payload.
    public DataTable MyDataTable { get; set; }
}

Desserializar um DataSet ou DataTable dessa maneira de um blob JSON não confiável não é seguro. Esse padrão é vulnerável a um ataque de negação de serviço. Esse ataque pode fazer o aplicativo falhar ou renderizá-lo sem resposta.

Observação

A Microsoft não garante nem premite a implementação de bibliotecas de terceiros, como Newtonsoft.Json. Essas informações são fornecidas para integridade e são precisas a partir do momento desta gravação.

Desserializar um DataSet ou DataTable via BinaryFormatter

Nunca use BinaryFormatter, NetDataContractSerializer, SoapFormatter ou formatadores não seguros para desserializar uma instância DataSet ou DataTable de um payload não confiável:

  • Isso é suscetível a um ataque de execução de código remoto completo.
  • O uso de um SerializationBinder personalizado não é suficiente para evitar esse ataque.

Substituições seguras

Para aplicativos que:

  • Aceite DataSet ou DataTable por meio de um ponto de extremidade SOAP .asmx ou um ponto de extremidade WCF.
  • Desserializar dados não confiáveis em uma instância de DataSet ou DataTable.

Considere substituir o modelo de objeto para usar o Entity Framework. Entity Framework:

  • É uma estrutura avançada, moderna e orientada a objetos que pode representar dados relacionais.
  • Traz um ecossistema diversificado de provedores de banco de dados para facilitar o projeto de consultas de banco de dados por meio de seus modelos de objeto do Entity Framework.
  • Oferece proteções internas ao desserializar dados de fontes não confiáveis.

Para aplicativos que usam pontos de extremidade SOAP .aspx, considere alterar esses pontos de extremidade para usar o WCF. O WCF é uma substituição mais completa para serviços Web .asmx. Os pontos de extremidade do WCF podem ser expostos via SOAP para compatibilidade com os chamadores existentes.

Analisadores de código

As regras de segurança do analisador de código executadas quando o código-fonte é compilado, podem ajudar a encontrar vulnerabilidades relacionadas a esse problema de segurança no código C# e no Visual Basic. Microsoft.CodeAnalysis.FxCopAnalyzers é um pacote NuGet de analisadores de código distribuído em nuget.org.

Para obter uma visão geral dos analisadores de código, consulte Visão geral dos analisadores de código-fonte.

Habilite as seguintes regras Microsoft.CodeAnalysis.FxCopAnalyzers:

  • CA2350: não use DataTable.ReadXml() com dados não confiáveis
  • CA2351: não use o DataSet.ReadXml() com dados não confiáveis
  • CA2352: DataSet ou DataTable não seguros no tipo serializável podem ser vulneráveis a ataques de execução de código remoto
  • CA2353: DataSet ou DataTable não seguros no tipo serializável
  • CA2354: DataSet ou DataTable não seguros no grafo de objetos desserializados podem ser vulneráveis a ataques de execução de código remoto
  • CA2355: o tipo DataSet ou DataTable não seguro foi encontrado em um grafo de objetos desserializável
  • CA2356: o tipo DataSet ou DataTable não seguro no grafo de objetos desserializável da Webh
  • CA2361: verifique se a classe gerada automaticamente que contém DataSet.ReadXml() não é usada quando os dados não são confiáveis
  • CA2362: DataSet ou DataTable não seguros em um tipo serializável gerado automaticamente podem ser vulneráveis a ataques de execução remota de código

Para obter mais informações sobre como configurar regras, consulte Usar analisadores de código.

As novas regras de segurança estão disponíveis nos seguintes pacotes NuGet:

  • Microsoft.CodeAnalysis.FxCopAnalyzers 3.3.0: para Visual Studio 2019 versão 16.3 ou posterior
  • Microsoft.CodeAnalysis.FxCopAnalyzers2.9.11: para Visual Studio 2017 versão 15.9 ou posterior