Пути к коду в кодировке UTF-7 устарели
Кодировка UTF-7 больше не используется широко в приложениях, и многие спецификации теперь запрещают использовать ее при обмене. Кроме того, иногда она служит вектором атаки в приложениях, которые не предусматривают получение данных в этой кодировке. Корпорация Майкрософт предостерегает от использования класса System.Text.UTF7Encoding, так как он не выполняет обнаружение ошибок.
Таким образом, свойство Encoding.UTF7 и конструкторы UTF7Encoding теперь также считаются устаревшими. Кроме того, методы Encoding.GetEncoding и Encoding.GetEncodings больше не позволяют определять UTF-7
.
Описание изменения
Ранее экземпляр кодировки UTF-7 можно было создать с помощью API Encoding.GetEncoding. Например:
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() не включает кодировку UTF-7 в возвращаемый массив EncodingInfo. Кодировка исключается, так как нельзя создать ее экземпляр.
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")
с именем кодировки, полученным от ненадежного источника. Например, веб-клиент или сервер может взять фрагмент charset
из заголовка Content-Type
и передать его значение непосредственно в Encoding.GetEncoding
без проверки. Это позволяет вредоносной конечной точке указать Content-Type: ...; charset=utf-7
, что может привести к сбою принимающего приложения.
Кроме того, отключение путей к коду в UTF-7 позволяет оптимизировать работу компиляторов, например используемых в Blazor. При этом такие пути к коду полностью удаляются из полученного приложения. В результате скомпилированные приложения работают более эффективно и занимают меньше места на диске.
Представленные версии
5,0
Рекомендуемое действие
В большинстве случаев никаких дополнительных действий от вас не требуется. Но если в приложении ранее были активированы пути к коду в UTF-7, воспользуйтесь приведенными ниже рекомендациями.
Если приложение вызывает метод Encoding.GetEncoding с неизвестными именами кодировки, полученными от ненадежного источника:
Вместо этого рекомендуется выполнять проверку имен кодировки по списку разрешенных. Этот настраиваемый список разрешенных кодировок должен по меньшей мере содержать стандартную отраслевую кодировку UTF-8. В зависимости от потребностей ваших клиентов и нормативных требований вам может также понадобится разрешить кодировки для определенных регионов, например GB18030.
Если вы не создадите список разрешенных кодировок, метод Encoding.GetEncoding будет возвращать все значения Encoding, которые встроены в систему или зарегистрированы с помощью настраиваемого класса EncodingProvider. Проверьте требования службы, чтобы убедиться, что такое поведение допустимо. По умолчанию кодировка 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:
Вы можете отключить предупреждение
SYSLIB0001
в коде или в файле .csproj проекта.#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()