Les chemins d’accès en code UTF-7 sont obsolètes

L’encodage UTF-7 n’est plus largement utilisé par les applications et de nombreuses spécifications interdisent désormais son utilisation dans l’échange. Il est également parfois utilisé comme vecteur d’attaque dans les applications qui ne prévoient pas rencontrer des données encodées en UTF-7. Microsoft met en garde contre l’utilisation de System.Text.UTF7Encoding, car il ne fournit pas de détection d’erreurs.

Par conséquent, la propriété Encoding.UTF7 et les constructeurs UTF7Encoding sont désormais obsolètes. En outre, Encoding.GetEncoding et Encoding.GetEncodings ne vous permettent plus de spécifier UTF-7.

Description de la modification

Auparavant, vous pouviez créer une instance de l’encodage UTF-7 à l’aide des API Encoding.GetEncoding. Par exemple :

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

En outre, une instance qui représente l’encodage UTF-7 a été énumérée par la méthode Encoding.GetEncodings(), qui énumère toutes les instances Encoding inscrites sur le système.

À compter de .NET 5, la propriété Encoding.UTF7 et les constructeurs UTF7Encoding sont obsolètes et produisent un avertissement SYSLIB0001. Toutefois, pour réduire le nombre d’avertissements que les appelants reçoivent lors de l’utilisation de la classe UTF7Encoding, le type UTF7Encoding lui-même n’est pas marqué comme obsolète.

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

En outre, les méthodes Encoding.GetEncodingtraitent le nom d’encodage utf-7 et la page de codes 65000 comme unknown. Le fait de traiter l’encodage comme unknown entraîne la levée d’une exception ArgumentException par la méthode.

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

Enfin, la méthode Encoding.GetEncodings() n’inclut pas l’encodage UTF-7 dans le tableau EncodingInfo qu’elle retourne. L’encodage est exclu, car il ne peut pas être instancié.

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

Raison du changement

De nombreuses applications appellent Encoding.GetEncoding("encoding-name") avec une valeur de nom d’encodage fournie par une source non approuvée. Par exemple, un client web ou un serveur peut prendre la partie charset de l’en-tête Content-Type et passer la valeur directement à Encoding.GetEncoding sans la valider. Cela peut permettre à un point de terminaison malveillant de spécifier Content-Type: ...; charset=utf-7, ce qui peut entraîner un comportement incorrect de l’application réceptrice.

En outre, la désactivation des chemins du code UTF-7 permet d’optimiser les compilateurs, tels que ceux utilisés par Blazor, pour supprimer entièrement ces chemins du code de l’application résultante. Par conséquent, les applications compilées s’exécutent plus efficacement et prennent moins d’espace disque.

Version introduite

5,0

Dans la plupart des cas, vous n’avez pas besoin d’agir. Toutefois, pour les applications qui ont précédemment activé des chemins du code liés à UTF-7, tenez compte des conseils qui suivent.

  • Si votre application appelle Encoding.GetEncoding avec des noms d’encodage inconnus fournis par une source non approuvée :

    Au lieu de cela, comparez les noms d’encodage à une liste d’autorisation configurable. La liste d’autorisation configurable doit inclure au minimum la norme « utf-8 ». Selon vos clients et les exigences réglementaires, vous devrez peut-être également autoriser les encodages spécifiques à la région, tels que « GB18030 ».

    Si vous n’implémentez pas de liste d’autorisation, Encoding.GetEncoding retourne les éléments Encoding intégrés au système ou inscrits via un EncodingProvider personnalisé. Auditez les exigences de votre service pour valider le comportement. UTF-7 continue d’être désactivé par défaut, sauf si votre application réactive le commutateur de compatibilité mentionné plus loin dans cet article.

  • Si vous utilisez Encoding.UTF7 ou UTF7Encoding dans votre propre protocole ou format de fichier :

    Basculez vers à l’utilisation de Encoding.UTF8 ou UTF8Encoding. UTF-8 est une norme du secteur et est largement pris en charge dans les langages, les systèmes d’exploitation et les runtimes. L’utilisation d’UTF-8 facilite la maintenance future de votre code et améliore son interopérabilité avec le reste de l’écosystème.

  • Si vous comparez une instance Encoding à Encoding.UTF7 :

    Au lieu de cela, envisagez d’effectuer une vérification par rapport à la page de codes UTF-7 bien connue, qui est 65000. En comparant la page de codes, vous évitez l’avertissement et gérez également certains cas de périphérie, par exemple si quelqu’un a appelé new UTF7Encoding() ou sous-classé le type.

    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.
        }
    }
    
  • Vous devez utiliser Encoding.UTF7 ou UTF7Encoding :

    Vous pouvez supprimer l’avertissement SYSLIB0001 dans le code ou dans le fichier .csproj de votre projet.

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

    Notes

    La suppression de SYSLIB0001 désactive uniquement les avertissements d’obsolescence Encoding.UTF7 et UTF7Encoding. Il ne désactive pas d’autres avertissements ou ne modifie pas le comportement des API telles que Encoding.GetEncoding.

  • Si vous devez prendre en charge Encoding.GetEncoding("utf-7", ...) :

    Vous pouvez réactiver la prise en charge de ce paramètre via un commutateur de compatibilité. Ce commutateur de compatibilité peut être spécifié dans le fichier .csproj de l’application ou dans un fichier config du runtime, comme illustré dans les exemples suivants.

    Dans le fichier .csproj de l’application :

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

    Dans le fichier runtimeconfig.template.json de l’application :

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

    Conseil

    Si vous réactivez la prise en charge d’UTF-7, vous devez effectuer une évaluation de sécurité du code qui appelle Encoding.GetEncoding.

API affectées