UTF-7-Codepfade sind veraltet

Die UTF-7-Codierung wird in Anwendungen kaum noch verwendet, und viele Spezifikationen verbieten ihre Verwendung im Austausch. Sie wird zuweilen auch in Anwendungen, die keine UTF-7-codierten Daten erwarten, als Angriffsvektor verwendet. Microsoft warnt vor der Verwendung von System.Text.UTF7Encoding, weil es keine Fehlererkennung bereitstellt.

Folglich sind die Encoding.UTF7-Eigenschaft und der UTF7Encoding-Konstruktor jetzt ebenfalls veraltet. Darüber hinaus erlauben Encoding.GetEncoding und Encoding.GetEncodings nicht mehr die Angabe von UTF-7.

Änderungsbeschreibung

Bisher konnten Sie mithilfe der Encoding.GetEncoding-APIs eine Instanz der UTF-7-Codierung erstellen. Zum Beispiel:

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

Darüber hinaus wurde eine Instanz, die die UTF-7-Codierung repräsentiert, durch die Encoding.GetEncodings()-Methode enumeriert, wodurch alle im System registrierten Encoding-Instanzen enumeriert wurden.

Ab .NET 5 sind die Encoding.UTF7-Eigenschaft und die UTF7Encoding-Konstruktoren veraltet und erzeugen die Warnung SYSLIB0001. Um jedoch die Anzahl von Warnungen zu reduzieren, die Aufrufer bei Verwendung der UTF7Encoding-Klasse empfangen, wurde der UTF7Encoding-Typ selbst nicht als veraltet markiert.

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

Darüber hinaus behandeln die Encoding.GetEncoding-Methoden den Codierungsnamen utf-7 und die Codepage 65000 als unknown. Da die Codierung als unknown behandelt wird, löst die Methode eine ArgumentException aus.

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

Außerdem schließt die Encoding.GetEncodings()-Methode die UTF-7-Codierung nicht in das von ihr zurückgegebene EncodingInfo-Array ein. Die Codierung wird ausgeschlossen, weil sie nicht instanziiert werden kann.

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

Grund für die Änderung

Viele Anwendungen rufen Encoding.GetEncoding("encoding-name") mit einem Wert für den Codierungsnamen auf, der von einer nicht vertrauenswürdigen Quelle bereitgestellt wird. Beispielsweise könnte ein Webclient oder Webserver den charset-Teil des Content-Type-Headers verwenden und den Wert direkt an Encoding.GetEncoding übergeben, ohne ihn zu validieren. So könnte ein schädlicher Endpunkt Content-Type: ...; charset=utf-7 angeben, was zu einem unerwünschten Verhalten bei der empfangenden Anwendung führen könnte.

Darüber hinaus ermöglicht die Deaktivierung von UTF-7-Codepfaden es Optimierungscompilern, wie beispielsweise denen von Blazor, diese Codepfade vollständig aus der resultierenden Anwendung zu entfernen. Im Ergebnis werden die kompilierten Anwendungen effizienter ausgeführt und belegen weniger Speicherplatz auf dem Datenträger.

Eingeführt in Version

5.0

In denen meisten Fällen müssen Sie keine Maßnahmen ergreifen. Wenn Sie jedoch über Apps verfügen, in denen zuvor UTF-7-bezogene Codepfade aktiviert waren, sollten Sie sich die folgende Anleitung ansehen.

  • Wenn Ihre App Encoding.GetEncoding mit unbekannten Codierungsnamen aufruft, die aus einer nicht vertrauenswürdigen Quelle stammen, gehen Sie wie folgt vor:

    Vergleichen Sie stattdessen die Codierungsnamen mit einer konfigurierbaren Zulassungsliste. Die konfigurierbare Zulassungsliste sollte mindestens den Branchenstandard „UTF-8“ enthalten. Je nach vorhandenen Clients und gesetzlichen Anforderungen müssen möglicherweise auch regionsspezifische Codierungen zulassen, wie z. B. „GB18030“.

    Wenn Sie keine Zulassungsliste implementieren, gibt Encoding.GetEncoding jede Encoding zurück, die im System integriert ist oder über einen benutzerdefinierten EncodingProvider registriert ist. Überprüfen Sie die Anforderungen Ihres Diensts, um sich zu vergewissern, dass dies das gewünschte Verhalten ist. UTF-7 ist weiterhin standardmäßig deaktiviert, es sei denn, Ihre Anwendung aktiviert den Kompatibilitätsschalter wieder, der weiter unten in diesem Artikel beschrieben wird.

  • Wenn Sie Encoding.UTF7 oder UTF7Encoding in Ihrem eigenen Protokoll oder Dateiformat verwenden, gehen Sie folgendermaßen vor:

    Wechseln Sie zu Encoding.UTF8 oder UTF8Encoding. UTF-8 ist ein Branchenstandard und wird über Sprachen, Betriebssysteme und Runtimes hinweg flächendeckend unterstützt. Die Verwendung von UTF-8 vereinfacht die zukünftige Wartung Ihres Codes und sorgt für mehr Interoperabilität mit dem Rest des Ökosystems.

  • Wenn Sie eine Encoding-Instanz mit Encoding.UTF7 vergleichen, gehen Sie folgendermaßen vor:

    Erwägen Sie stattdessen eine Überprüfung anhand der bekannten UTF-7-Codepage, die 65000 lautet. Durch Vergleichen mit der Codepage vermeiden Sie die Warnung und können außerdem einige Sonderfälle behandeln, wenn beispielsweise jemand new UTF7Encoding() aufgerufen oder Unterklassen des Typs erstellt hat.

    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.
        }
    }
    
  • Wenn Sie Encoding.UTF7 oder UTF7Encodingverwenden müssen, gilt Folgendes:

    Sie können die SYSLIB0001-Warnung im Code oder in der CSPROJ-Datei Ihres Projekts unterdrücken.

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

    Hinweis

    Das Unterdrücken von SYSLIB0001 deaktiviert nur die Warnungen, dass Encoding.UTF7 und UTF7Encoding veraltet sind. Andere Warnungen werden nicht deaktiviert, und das Verhalten von APIs wie Encoding.GetEncoding wird nicht geändert.

  • Wenn Sie Encoding.GetEncoding("utf-7", ...) unterstützen müssen, gehen Sie wie folgt vor:

    Sie können die Unterstützung über einen Kompatibilitätsschalter wieder aktivieren. Dieser Kompatibilitätsschalter kann in der CSPROJ-Datei der Anwendung oder in einer Laufzeitkonfigurationsdatei angegeben werden, wie in den folgenden Beispielen gezeigt.

    In der CSPROJ-Datei der Anwendung:

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

    In der runtimeconfig.template.json-Datei der Anwendung:

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

    Tipp

    Wenn Sie die Unterstützung für UTF-7 wieder aktivieren, sollten Sie eine Sicherheitsüberprüfung des Codes durchführen, der Encoding.GetEncoding aufruft.

Betroffene APIs