Udostępnij za pośrednictwem


Ścieżki kodu UTF-7 są przestarzałe

Kodowanie UTF-7 nie jest już szeroko używane między aplikacjami, a wiele specyfikacji obecnie zabrania używania w wymiennych. Jest on również czasami używany jako wektor ataku w aplikacjach, które nie przewidują napotkania danych zakodowanych w formacie UTF-7. Firma Microsoft ostrzega przed użyciem programu , System.Text.UTF7Encoding ponieważ nie zapewnia wykrywania błędów.

W związku z tym Encoding.UTF7 właściwości i UTF7Encoding konstruktory są teraz przestarzałe. Encoding.GetEncoding Ponadto i Encoding.GetEncodings nie zezwalaj już na określenie UTF-7elementu .

Opis zmiany

Wcześniej można było utworzyć wystąpienie kodowania UTF-7 przy użyciu Encoding.GetEncoding interfejsów API. Na przykład:

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

Ponadto wystąpienie reprezentujące kodowanie UTF-7 zostało wyliczone przez Encoding.GetEncodings() metodę , która wylicza wszystkie Encoding wystąpienia zarejestrowane w systemie.

Począwszy od platformy .NET 5, Encoding.UTF7 właściwość i UTF7Encoding konstruktory są przestarzałe i generują ostrzeżenie SYSLIB0001. Jednak aby zmniejszyć liczbę ostrzeżeń odbieranych podczas korzystania z UTF7Encoding klasy, UTF7Encoding sam typ nie jest oznaczony jako przestarzały.

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

Encoding.GetEncoding Ponadto metody traktują nazwę utf-7 kodowania i stronę 65000 kodu jako unknown. Traktowanie kodowania jako powoduje, że unknown metoda zgłasza błąd ArgumentException.

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

Encoding.GetEncodings() Na koniec metoda nie zawiera kodowania UTF-7 w tablicyEncodingInfo, która zwraca. Kodowanie jest wykluczone, ponieważ nie można utworzyć wystąpienia.

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

Przyczyna wprowadzenia zmiany

Wiele aplikacji wywołuje Encoding.GetEncoding("encoding-name") metodę z wartością nazwy kodowania, która jest dostarczana przez niezaufane źródło. Na przykład klient internetowy lub serwer może pobrać charset część nagłówka Content-Type i przekazać wartość bezpośrednio do Encoding.GetEncoding bez jego walidacji. Może to umożliwić określenie złośliwego punktu końcowego, co może spowodować Content-Type: ...; charset=utf-7błędne zachowanie aplikacji odbieranej.

Ponadto wyłączenie ścieżek kodu UTF-7 umożliwia optymalizowanie kompilatorów, takich jak te używane przez platformę Blazor, w celu całkowitego usunięcia tych ścieżek kodu z wynikowej aplikacji. W rezultacie skompilowane aplikacje działają wydajniej i zajmują mniej miejsca na dysku.

Wprowadzona wersja

5,0

W większości przypadków nie trzeba podejmować żadnych działań. Jednak w przypadku aplikacji, które wcześniej aktywowały ścieżki kodu związane z protokołem UTF-7, należy wziąć pod uwagę poniższe wskazówki.

  • Jeśli aplikacja wywołuje Encoding.GetEncoding nieznane nazwy kodowania dostarczone przez niezaufane źródło:

    Zamiast tego porównaj nazwy kodowania z konfigurowalną listą dozwolonych. Konfigurowalna lista dozwolonych powinna zawierać co najmniej standard branżowy "utf-8". W zależności od klientów i wymagań prawnych może być również konieczne zezwolenie na kodowanie specyficzne dla regionu, takie jak "GB18030".

    Jeśli nie zaimplementujesz listy dozwolonych, Encoding.GetEncoding zostanie zwrócona dowolna Encoding wbudowana w system lub zarejestrowana za pomocą niestandardowego EncodingProviderelementu . Przeprowadź inspekcję wymagań usługi, aby sprawdzić, czy jest to pożądane zachowanie. Protokół UTF-7 jest domyślnie wyłączony, chyba że aplikacja ponownie włączy przełącznik zgodności wymieniony w dalszej części tego artykułu.

  • Jeśli używasz Encoding.UTF7 własnego protokołu lub formatu pliku:UTF7Encoding

    Przełącz się na przy użyciu polecenia Encoding.UTF8 lub UTF8Encoding. UTF-8 jest standardem branżowym i jest powszechnie obsługiwany w różnych językach, systemach operacyjnych i środowiskach uruchomieniowych. Korzystanie z protokołu UTF-8 ułatwia przyszłą konserwację kodu i zwiększa jego współdziałanie z resztą ekosystemu.

  • Jeśli porównujesz wystąpienie z elementem EncodingEncoding.UTF7:

    Zamiast tego rozważ przeprowadzenie kontroli na dobrze znanej stronie kodowej UTF-7, czyli 65000. Porównując się ze stroną kodu, należy unikać ostrzeżenia, a także obsługiwać niektóre przypadki brzegowe, takie jak wywołanie new UTF7Encoding() lub podklasa typu.

    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.
        }
    }
    
  • Jeśli musisz użyć polecenia Encoding.UTF7 lub UTF7Encoding:

    Ostrzeżenie można pominąć SYSLIB0001 w kodzie lub w pliku csproj projektu.

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

    Uwaga

    Pomijanie SYSLIB0001 powoduje wyłączenie Encoding.UTF7 tylko ostrzeżeń i UTF7Encoding obsoletion. Nie wyłącza żadnych innych ostrzeżeń ani nie zmienia zachowania interfejsów API, takich jak Encoding.GetEncoding.

  • Jeśli musisz obsługiwać program Encoding.GetEncoding("utf-7", ...):

    Możesz ponownie włączyć obsługę tej funkcji za pośrednictwem przełącznika zgodności. Ten przełącznik zgodności można określić w pliku csproj aplikacji lub w pliku konfiguracji środowiska uruchomieniowego, jak pokazano w poniższych przykładach.

    W pliku csproj aplikacji:

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

    W pliku runtimeconfig.template.json aplikacji:

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

    Napiwek

    Jeśli ponownie włączysz obsługę protokołu UTF-7, należy przeprowadzić przegląd zabezpieczeń kodu, który wywołuje metodę Encoding.GetEncoding.

Dotyczy interfejsów API