I percorsi del codice UTF-7 sono obsoleti

La codifica UTF-7 non è più in uso tra le applicazioni e molte specifiche ora ne vietano l'uso nell'interscambio. Viene usata anche occasionalmente come vettore di attacco nelle applicazioni che non prevedono l'incontro dei dati con codifica UTF-7. Microsoft mette in guardia dall'uso di System.Text.UTF7Encoding poichè non fornisce il rilevamento degli errori.

Di conseguenza, la proprietà Encoding.UTF7 e i costruttori UTF7Encoding sono ormai obsoleti. Inoltre, Encoding.GetEncoding e Encoding.GetEncodings non consentono più di specificare UTF-7.

Descrizione delle modifiche

In precedenza, era possibile creare un'istanza della codifica UTF-7 usando le API Encoding.GetEncoding. Ad esempio:

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

Inoltre, un'istanza che rappresenta la codifica UTF-7 è stata enumerata dal metodo Encoding.GetEncodings(), che enumera tutte le istanze Encoding registrate nel sistema.

A partire da .NET 5, la proprietà Encoding.UTF7 e i costruttori UTF7Encoding sono obsoleti e generano un avviso SYSLIB0001. Tuttavia, per ridurre il numero di avvisi ricevuti dai chiamanti quando usano la classe UTF7Encoding, il tipo UTF7Encoding stesso non è contrassegnato come 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!");

Inoltre, i metodi Encoding.GetEncoding considerano il nome di codifica utf-7 e la tabella codici 65000 come unknown. Se si usa la codifica come unknown, il metodo genera ArgumentException.

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

Infine, il metodo Encoding.GetEncodings() non include la codifica UTF-7 nella matrice EncodingInfo restituita. La codifica viene esclusa perché non può essere creata un'istanza.

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

Motivo della modifica

Molte applicazioni chiamano Encoding.GetEncoding("encoding-name") con un valore del nome di codifica fornito da un'origine non attendibile. Ad esempio, un client Web o un server potrebbe accettare la charset parte dell'intestazione Content-Type e passare il valore direttamente a Encoding.GetEncoding senza convalidarlo. Ciò potrebbe consentire a un endpoint dannoso di specificare Content-Type: ...; charset=utf-7, che potrebbe causare un comportamento errato dell'applicazione ricevente.

Inoltre, la disabilitazione dei percorsi di codice UTF-7 consente ai compilatori ottimizzatori, ad esempio quelli usati da Blazor, di rimuovere completamente tali percorsi del codice dall'applicazione risultante. Di conseguenza, le applicazioni compilate vengono eseguite in modo più efficiente e richiedono meno spazio su disco.

Versione con introduzione

5.0

Nella maggior parte dei casi, non è necessario eseguire alcuna azione. Tuttavia, per le app che hanno attivato in precedenza i percorsi di codice correlati a UTF-7, prendere in considerazione le indicazioni seguenti.

  • Se l'app chiama Encoding.GetEncoding con nomi di codifica sconosciuti forniti da un'origine non attendibile:

    Confrontare invece i nomi di codifica con un elenco elementi consentiti configurabili. L'elenco di elementi consenti configurabile deve includere almeno lo standard di settore "utf-8". A seconda dei client e dei requisiti normativi, potrebbe anche essere necessario consentire codifiche specifiche dell'area, ad esempio "GB18030".

    Se non si implementa un elenco di elementi consentiti, Encoding.GetEncoding restituirà tutti gli elementi Encoding incorporati nel sistema o registrati tramite un oggetto personalizzato EncodingProvider. Controllare i requisiti del servizio per convalidare che si tratta del comportamento desiderato. UTF-7 continua a essere disabilitato per impostazione predefinita, a meno che l'applicazione non riabiliti l'opzione di compatibilità indicata più avanti in questo articolo.

  • Se si usa Encoding.UTF7 o UTF7Encoding all'interno del proprio protocollo o formato di file:

    Passare all'uso di Encoding.UTF8 o UTF8Encoding. UTF-8 è uno standard di settore ed è ampiamente supportato in linguaggi, sistemi operativi e runtime. L'uso di UTF-8 semplifica la manutenzione futura del codice e lo rende più interoperabile con il resto dell'ecosistema.

  • Se si confronta un'istanza Encoding con Encoding.UTF7:

    Prendere invece in considerazione l'esecuzione di un controllo sulla tabella codici UTF-7 nota, ovvero 65000. Confrontando con la tabella codici, si evita l'avviso e si gestiscono anche alcuni casi limite, come ad esempio se qualcuno ha chiamato new UTF7Encoding() o sottoclassato il 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.
        }
    }
    
  • È necessario utilizzare Encoding.UTF7 o UTF7Encoding:

    È possibile eliminare l'avviso SYSLIB0001 nel codice o all'interno del file .csproj del progetto.

    #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>
    

    Nota

    L'eliminazione di SYSLIB0001 disabilita solo gli avvisi obsoleti Encoding.UTF7 e UTF7Encoding. Ciò non disabilita altri avvisi o modifica il comportamento delle API come Encoding.GetEncoding.

  • Se è necessario supportare Encoding.GetEncoding("utf-7", ...):

    È possibile riabilitare il supporto per questo elemento tramite un commutatore di compatibilità. Questa opzione di compatibilità può essere specificata nel file .csproj dell'applicazione o in un file di configurazione runtime, come illustrato negli esempi seguenti.

    Nel file .csproj dell'applicazione:

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

    Nel file runtimeconfig.template.json dell'applicazione:

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

    Suggerimento

    Se si riabilita il supporto per UTF-7, occorre eseguire una verifica della sicurezza del codice che chiama Encoding.GetEncoding.

API interessate