Share via


Os caminhos do código UTF-7 estão obsoletos

A codificação UTF-7 não está mais em uso amplo entre aplicativos, e muitas especificações agora proíbem seu uso no intercâmbio. Ele também é ocasionalmente usado como um vetor de ataque em aplicativos que não preveem encontrar dados codificados em UTF-7. A Microsoft alerta contra o uso porque System.Text.UTF7Encoding não fornece detecção de erros.

Consequentemente, a propriedade Encoding.UTF7 e os construtores UTF7Encoding agora estão obsoletos. Além disso, Encoding.GetEncoding e Encoding.GetEncodings não permitem mais que você especifique UTF-7.

Descrição das alterações

Anteriormente, era possível criar uma instância da codificação UTF-7 usando as APIs Encoding.GetEncoding. Por exemplo:

Encoding enc1 = Encoding.GetEncoding("utf-7"); // By name.
Encoding enc2 = Encoding.GetEncoding(65000); // By code page.

Além disso, uma instância que representa a codificação UTF-7 foi enumerada pelo método Encoding.GetEncodings(), que enumera todas as instâncias de Encoding registradas no sistema.

A partir do .NET 5, a propriedade Encoding.UTF7 e os construtores UTF7Encoding estão obsoletos e produzem o aviso SYSLIB0001. No entanto, para reduzir o número de avisos que os chamadores recebem ao usar a classe UTF7Encoding, o tipo UTF7Encoding em si não está marcado como obsoleto.

// The next line generates warning SYSLIB0001.
UTF7Encoding enc = new UTF7Encoding();
// The next line does not generate a warning.
byte[] bytes = enc.GetBytes("Hello world!");

Além disso, os métodos Encoding.GetEncoding tratam o nome de codificação utf-7 e a página de código 65000 como unknown. Tratar a codificação como unknown faz com que o método gere uma ArgumentException.

// Throws ArgumentException, same as calling Encoding.GetEncoding("unknown").
Encoding enc = Encoding.GetEncoding("utf-7");

Por fim, o método Encoding.GetEncodings() não inclui a codificação UTF-7 na matriz EncodingInfo retornada. A codificação é excluída porque não pode ser instanciada.

foreach (EncodingInfo encInfo in Encoding.GetEncodings())
{
    // The next line would throw if GetEncodings included UTF-7.
    Encoding enc = Encoding.GetEncoding(encInfo.Name);
}

Motivo da alteração

Muitos aplicativos chamam Encoding.GetEncoding("encoding-name") com um valor de nome de codificação fornecido por uma fonte não confiável. Por exemplo, um cliente ou servidor Web pode pegar a parte charset do cabeçalho Content-Type e passar o valor diretamente para Encoding.GetEncoding sem validá-lo. Isso pode permitir que um ponto de extremidade mal-intencionado especifique Content-Type: ...; charset=utf-7, o que pode fazer com que o aplicativo receptor se comporte indevidamente.

Além disso, desabilitar caminhos de código UTF-7 permite otimizar compiladores, como os usados pelo Blazor, para remover esses caminhos de código inteiramente do aplicativo resultante. Consequentemente, os aplicativos compilados são executados com mais eficiência e ocupam menos espaço em disco.

Versão introduzida

5,0

Na maioria dos casos, você não precisa tomar nenhuma ação. No entanto, para aplicativos que ativaram anteriormente caminhos de código relacionados ao UTF-7, considere as diretrizes a seguir.

  • Se o aplicativo chamar Encoding.GetEncoding com nomes de codificação desconhecidos fornecidos por uma fonte não confiável:

    Em vez disso, compare os nomes de codificação com uma lista de permissões configurável. A lista de permissões configurável deve, no mínimo, incluir o padrão do setor "utf-8". Dependendo dos clientes e dos requisitos regulatórios, talvez você também precise permitir codificações específicas da região, como "GB18030".

    Se você não implementar uma lista de permissões, Encoding.GetEncoding retornará qualquer Encoding que esteja incorporada ao sistema ou que esteja registrada por meio de um EncodingProvider personalizado. Faça a auditoria dos requisitos do serviço para validar se esse é o comportamento desejado. O UTF-7 continua a ser desabilitado por padrão, a menos que seu aplicativo habilite novamente a opção de compatibilidade mencionada posteriormente neste artigo.

  • Se você estiver usando Encoding.UTF7 ou UTF7Encoding dentro de seu próprio protocolo ou formato de arquivo:

    Mude para usar Encoding.UTF8 ou UTF8Encoding. O UTF-8 é um padrão do setor e é amplamente compatível com linguagens, sistemas operacionais e runtimes. O uso do UTF-8 facilita a manutenção futura do código e o torna mais interoperável com o restante do ecossistema.

  • Se você estiver comparando uma instância Encoding com Encoding.UTF7:

    Em vez disso, considere executar uma verificação na conhecida página de código UTF-7, que é 65000. Ao comparar com a página de código, você evita o aviso e também lida com alguns casos de borda, como se alguém chamasse new UTF7Encoding() ou definisse uma subclasse do tipo.

    void DoSomething(Encoding enc)
    {
        // Don't perform the check this way.
        // It produces a warning and misses some edge cases.
        if (enc == Encoding.UTF7)
        {
            // Encoding is UTF-7.
        }
    
        // Instead, perform the check this way.
        if (enc != null && enc.CodePage == 65000)
        {
            // Encoding is UTF-7.
        }
    }
    
  • Você deve usar Encoding.UTF7 ou UTF7Encoding:

    Você pode suprimir o aviso SYSLIB0001 no código ou no arquivo .csproj do projeto.

    #pragma warning disable SYSLIB0001 // Disable the warning.
    Encoding enc = Encoding.UTF7;
    #pragma warning restore SYSLIB0001 // Re-enable the warning.
    
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
       <TargetFramework>net5.0</TargetFramework>
       <!-- NoWarn below suppresses SYSLIB0001 project-wide -->
       <NoWarn>$(NoWarn);SYSLIB0001</NoWarn>
      </PropertyGroup>
    </Project>
    

    Observação

    Suprimir SYSLIB0001 só desabilita os avisos de obsolescência Encoding.UTF7 e UTF7Encoding. Não desabilita outros avisos nem altera o comportamento de APIs, como Encoding.GetEncoding.

  • Se você precisar dar suporte a Encoding.GetEncoding("utf-7", ...):

    Poderá habilitar novamente o suporte por meio de uma opção de compatibilidade. Essa opção de compatibilidade pode ser especificada no arquivo .csproj do aplicativo ou em um arquivo de configuração de runtime, conforme mostrado nos exemplos a seguir.

    No arquivo .csproj do aplicativo:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
       <TargetFramework>net5.0</TargetFramework>
       <!-- Re-enable support for UTF-7 -->
       <EnableUnsafeUTF7Encoding>true</EnableUnsafeUTF7Encoding>
      </PropertyGroup>
    </Project>
    

    No arquivo runtimeconfig.template.json do aplicativo:

    {
      "configProperties": {
        "System.Text.Encoding.EnableUnsafeUTF7Encoding": true
      }
    }
    

    Dica

    Se você reabilitar o suporte para UTF-7, deverá executar uma revisão de segurança do código que chame Encoding.GetEncoding.

APIs afetadas