Бөлісу құралы:


CA3009: Проверьте код на уязвимости, связанные с внедрением XML

Свойство Значение
Идентификатор правила CA3009
Заголовок Проверьте код на уязвимости XML-инъекции.
Категория Безопасность
Исправление является критическим или не критическим неразрывный
Включен по умолчанию в .NET 10 Нет
Применимые языки C# и Visual Basic

Причина

Потенциально ненадежные входные данные HTTP-запроса попадают в необработанные выходные данные XML.

По умолчанию это правило анализирует всю базу кода, но такое поведение можно настроить.

Описание правила

При работе с ненадежными входными данными следует учитывать вероятность атак путем внедрения кода XML. Злоумышленник может использовать внедрение кода XML для вставки специальных знаков в XML-документ, нарушая допустимость этого XML-документа. Также злоумышленник может добавлять произвольные XML-узлы в злонамеренных целях.

Это правило пытается найти места, где входные данные из HTTP-запросов достигают записи необработанных XML.

Примечание.

Это правило не может отслеживать данные между разными сборками. Например, если одна сборка считывает входные данные HTTP-запроса и передает результаты другой сборке, которая выполняет запись в необработанный XML, это правило не создаст предупреждение.

Примечание.

Можно указать, насколько глубоко это правило будет анализировать поток данных между вызовами методов. Сведения о настройке этого ограничения в файле EditorConfig см. на странице, посвященной конфигурации анализатора.

Устранение нарушений

Чтобы устранить нарушение, используйте один из следующих методов:

  • Не записывайте необработанные данные XML. Вместо этого используйте методы или свойства, которые кодируют выходные данные в безопасный для XML формат.
  • Закодируйте входные данные в XML перед записью необработанного XML.
  • Проверьте входные данные пользователя с помощью санитизаторов для преобразования примитивных типов и кодирования XML.

Когда лучше отключить предупреждения

Не отключайте предупреждения, создаваемые этим правилом.

Примеры псевдокода

Нарушение

В этом примере входные данные задаются свойством InnerXml корневого элемента. Учитывая входные данные, содержащие допустимый XML, злоумышленник может полностью изменить документ. Обратите внимание, что alice больше не имеет доступа после добавления входных данных пользователя в документ.

protected void Page_Load(object sender, EventArgs e)
{
    XmlDocument d = new XmlDocument();
    XmlElement root = d.CreateElement("root");
    d.AppendChild(root);

    XmlElement allowedUser = d.CreateElement("allowedUser");
    root.AppendChild(allowedUser);
    allowedUser.InnerXml = "alice";

    string input = Request.Form["in"];
    root.InnerXml = input;
}
Sub Page_Load(sender As Object, e As EventArgs)
    Dim d As XmlDocument = New XmlDocument()
    Dim root As XmlElement = d.CreateElement("root")
    d.AppendChild(root)

    Dim allowedUser As XmlElement = d.CreateElement("allowedUser")
    root.AppendChild(allowedUser)
    allowedUser.InnerXml = "alice"

    Dim input As String = Request.Form("in")
    root.InnerXml = input
End Sub

Если злоумышленник использует это для ввода: some text<allowedUser>oscar</allowedUser>xml-документ будет следующим:

<root>some text<allowedUser>oscar</allowedUser>
</root>

Решение

Чтобы устранить это нарушение, задайте входные данные свойству InnerText корневого элемента вместо InnerXml свойства.

protected void Page_Load(object sender, EventArgs e)
{
    XmlDocument d = new XmlDocument();
    XmlElement root = d.CreateElement("root");
    d.AppendChild(root);

    XmlElement allowedUser = d.CreateElement("allowedUser");
    root.AppendChild(allowedUser);
    allowedUser.InnerText = "alice";

    string input = Request.Form["in"];
    root.InnerText = input;
}
Sub Page_Load(sender As Object, e As EventArgs)
    Dim d As XmlDocument = New XmlDocument()
    Dim root As XmlElement = d.CreateElement("root")
    d.AppendChild(root)

    Dim allowedUser As XmlElement = d.CreateElement("allowedUser")
    root.AppendChild(allowedUser)
    allowedUser.InnerText = "alice"

    Dim input As String = Request.Form("in")
    root.InnerText = input
End Sub

Если злоумышленник использует это для ввода: some text<allowedUser>oscar</allowedUser>xml-документ будет следующим:

<root>some text&lt;allowedUser&gt;oscar&lt;/allowedUser&gt;
<allowedUser>alice</allowedUser>
</root>

Настройка кода для анализа

Используйте следующие параметры, чтобы указать части базы кода, к которым будет применяться это правило.

Эти параметры можно настроить только для этого правила, для всех правил, к которым они применяются, или для всех правил в этой категории (безопасности), к которым они применяются. Дополнительные сведения см. в статье Параметры конфигурации правила качества кода.

Исключение определенных символов

Вы можете исключить определенные символы, такие как типы и методы, из анализа, задав параметр excluded_symbol_names. Например, чтобы указать, что правило не должно выполняться для какого-либо кода в типах с именем MyType, добавьте следующую пару "ключ-значение" в файл EDITORCONFIG в своем проекте:

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

Примечание.

Замените XXXX частью CAXXXX идентификатором применимого правила.

Допустимые форматы имени символа в значении параметра (разделенные |):

  • Только имя символа (включает все символы с этим именем, независимо от типа или пространства имен).
  • Полностью квалифицированные имена в формате идентификатора документации символа. Для каждого имени символа требуется префикс в виде символа, например M: для методов, T: для типов и N: для пространств имен.
  • .ctor используется для конструкторов, а .cctor — для статических конструкторов.

Примеры:

Значение параметра Итоги
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType Соответствует всем символам с именем MyType.
dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType1|MyType2 Соответствует всем символам с именем MyType1 или MyType2.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS.MyType.MyMethod(ParamType) Сопоставляет конкретный метод MyMethod с указанной полной сигнатурой.
dotnet_code_quality.CAXXXX.excluded_symbol_names = M:NS1.MyType1.MyMethod1(ParamType)|M:NS2.MyType2.MyMethod2(ParamType) Сопоставляет конкретные методы MyMethod1 и MyMethod2 с соответствующими полными квалифицированными сигнатурами.

Исключить определенные типы и их производные типы

Вы можете исключить определенные типы и производные типы из анализа, задав параметр excluded_type_names_with_derived_types. Например, чтобы указать, что правило не должно выполняться в каких-либо методах типов MyType и их производных типов, добавьте следующую пару "ключ-значение" в файл .editorconfig своего проекта:

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

Примечание.

Замените XXXX частью CAXXXX идентификатором применимого правила.

Допустимые форматы имени символа в значении параметра (разделенные |):

  • Только имя типа (включает все типы с этим именем, независимо от содержащего типа или пространства имен).
  • полные квалифицированные имена в формате идентификатора документации для символа, с необязательным префиксом T:.

Примеры:

Значение опции Итоги
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType Соответствует всем типам с именем MyType и всем их производным типам.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType1|MyType2 Соответствует всем типам с именем MyType1 или MyType2 и всем их производным типам.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS.MyType Соответствует конкретному типу MyType с заданным полным именем и всем производным от него типам.
dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = M:NS1.MyType1|M:NS2.MyType2 Соответствует конкретным типам MyType1 и MyType2 с заданным полным именем и всем производным от них типам.