UTF-7 程式碼路徑已過時
UTF-7 編碼已不再廣泛用於應用程式,而且許多規格現在已禁止其在交換中使用。 其也偶爾會用作非預期遇到 UTF-7 編碼資料之應用程式中的攻擊媒介。 使用 System.Text.UTF7Encoding 時 Microsoft 會發出警告,因為其不提供錯誤偵測。
因此,Encoding.UTF7 屬性和 UTF7Encoding 建構函式現在已淘汰。 此外,Encoding.GetEncoding 和 Encoding.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.UTF7 或 UTF7Encoding:
切換為使用 Encoding.UTF8 或 UTF8Encoding。 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.UTF7 或 UTF7Encoding:
您可以在程式碼或專案的 .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.UTF7 和 UTF7Encoding 淘汰警告。 這不會停用其他任何警告或變更 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
- System.Text.Encoding.UTF7
- UTF7Encoding()
- UTF7Encoding(Boolean)
- System.Text.Encoding.GetEncoding(Int32)
- System.Text.Encoding.GetEncoding(String)
- System.Text.Encoding.GetEncoding(Int32, EncoderFallback, DecoderFallback)
- System.Text.Encoding.GetEncoding(String, EncoderFallback, DecoderFallback)
- System.Text.Encoding.GetEncodings()