UTF-7 程式碼路徑已過時

UTF-7 編碼已不再廣泛用於應用程式,而且許多規格現在已禁止其在交換中使用。 其也偶爾會用作非預期遇到 UTF-7 編碼資料之應用程式中的攻擊媒介。 使用 System.Text.UTF7Encoding 時 Microsoft 會發出警告,因為其不提供錯誤偵測。

因此,Encoding.UTF7 屬性和 UTF7Encoding 建構函式現在已淘汰。 此外,Encoding.GetEncodingEncoding.GetEncodings 不再允許您指定 UTF-7

變更描述

先前,您可以使用 Encoding.GetEncoding API 建立 UTF-7 編碼的執行個體。 例如:

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

此外,表示 UTF-7 編碼的執行個體是由 Encoding.GetEncodings() 方法列舉,這會列舉系統上註冊的所有 Encoding 執行個體。

從 .NET 5 開始,Encoding.UTF7 屬性和 UTF7Encoding 建構函式已淘汰,並產生警告 SYSLIB0001。 不過,若要減少呼叫端在使用 UTF7Encoding 類別時收到的警告數目,UTF7Encoding 型別本身不會標示為已淘汰。

// 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 方法會將編碼名稱 utf-7 和字碼頁 65000 視為 unknown。 將編碼視為 unknown 會導致方法擲回 ArgumentException

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

最後,Encoding.GetEncodings() 方法不會在傳回的 EncodingInfo 陣列中包含 UTF-7 編碼。 因為無法具現化編碼,所以會排除編碼。

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

變更原因

許多應用程式會使用不受信任的來源所提供的編碼名稱值呼叫 Encoding.GetEncoding("encoding-name")。 例如,Web 用戶端或伺服器可能會取得 Content-Type 標頭的 charset 部分,並直接將值傳遞至 Encoding.GetEncoding,完全不需要加以驗證。 這可讓惡意端點指定 Content-Type: ...; charset=utf-7,因此可能會導致接收應用程式發生行為不當的情形。

此外,停用 UTF-7 程式碼路徑可讓編譯器最佳化,例如 Blazor 所使用的程式碼路徑,從產生的應用程式完全移除這些程式碼路徑。 因此,編譯的應用程式會更有效率地執行,並佔用較少的磁碟空間。

導入的版本

5.0

多數情況中,您將不需要採取任何動作。 不過,對於先前已啟用 UTF-7 相關程式碼路徑的應用程式,請考量下列指導方針。

  • 如果您的應用程式使用未受信任的來源所提供的未知編碼名稱呼叫 Encoding.GetEncoding

    相反地,請比較編碼名稱與可設定的允許清單。 可設定的允許清單至少應包含業界標準「utf-8」。 視您的用戶端和法規需求而定,您可能也需要允許區域特定的編碼,例如「GB18030」。

    如果您未實作允許清單,則 Encoding.GetEncoding 會傳回系統內建或透過自訂 EncodingProvider 註冊的任何 Encoding。 稽核服務的需求,以驗證這是所需的行為。 除非您的應用程式重新啟用本文稍後所述的相容性參數,否則預設會繼續停用 UTF-7。

  • 如果您在自己的通訊協定或檔案格式內使用 Encoding.UTF7UTF7Encoding

    切換為使用 Encoding.UTF8UTF8Encoding。 UTF-8 是業界標準,在語言、作業系統和執行階段之間廣受支援。 使用 UTF-8 可簡化程式碼的未來維護,並使其與生態系統的剩餘部分更容易互通。

  • 如果您要比較 Encoding 執行個體與 Encoding.UTF7

    相反地,請考慮對已知的 UTF-7 字碼頁執行檢查,也就是 65000。 藉由與字碼頁進行比較,您可以避免警告,同時處理某些極端案例,例如有人呼叫 new UTF7Encoding() 或子類別化型別。

    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.
        }
    }
    
  • 如果您必須使用 Encoding.UTF7UTF7Encoding

    您可以在程式碼或專案的 .csproj 檔案中隱藏 SYSLIB0001 警告。

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

    注意

    隱藏 SYSLIB0001 只會停用 Encoding.UTF7UTF7Encoding 淘汰警告。 這不會停用其他任何警告或變更 API 的行為,例如 Encoding.GetEncoding

  • 如果您必須支援 Encoding.GetEncoding("utf-7", ...)

    您可以透過相容性參數重新啟用此功能的支援。 此相容性參數可以在應用程式的 .csproj 檔案或執行階段設定檔中指定,如下列範例所示。

    在應用程式的 .csproj 檔案中:

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

    在應用程式的 runtimeconfig.template.json 檔案中:

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

    提示

    如果您重新啟用 UTF-7 的支援,您應該對呼叫 Encoding.GetEncoding 的程式碼執行安全性檢閱。

受影響的 API