CA3005: проверка кода уязвимостей внедрения LDAP

Свойство Значение
Идентификатор правила CA3005
Заголовок Проверьте код на наличие уязвимостей к внедрению LDAP
Категория Безопасность
Исправление является критическим или не критическим Не критическое
Включен по умолчанию в .NET 8 No

Причина

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

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

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

При работе с ненадежными входными данными следует учитывать вероятность атак путем внедрения кода в LDAP. Такая атака может позволить злоумышленнику выполнять вредоносные инструкции LDAP в информационных каталогах. Особенно уязвимы приложения, в которых динамические инструкции LDAP для доступа к службам каталогов создаются на основе данных, введенных пользователем.

Это правило пытается найти все места, где входные данные из HTTP-запросов могут попасть в инструкцию LDAP.

Примечание.

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

Примечание.

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

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

В той части инструкций LDAP, которая управляется действиями пользователя, можно применить следующие методы контроля:

  • разрешать ввод только символов из безопасного списка, не содержащего специальные знаки;
  • запретить ввод специальных знаков;
  • экранировать все специальные знаки.

Дополнительные сведения см. в памятке по предотвращению внедрения кода в LDAP на сайте OWASP.

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

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

Отключение предупреждений

Если вы просто хотите отключить одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить правило.

#pragma warning disable CA3005
// The code that's violating the rule is on this line.
#pragma warning restore CA3005

Чтобы отключить правило для файла, папки или проекта, задайте его серьезность none в файле конфигурации.

[*.{cs,vb}]
dotnet_diagnostic.CA3005.severity = none

Дополнительные сведения см. в разделе Практическое руководство. Скрытие предупреждений анализа кода.

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

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

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

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

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

dotnet_code_quality.CAXXXX.excluded_symbol_names = MyType

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

  • Только имя символа (включает все символы с этим именем, любого типа и в любом пространстве имен).
  • Полные имена в формате идентификатора документации для символа. Для каждого имени символа требуется префикс в виде символа, например 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 с соответствующими полными сигнатурами.

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

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

dotnet_code_quality.CAXXXX.excluded_type_names_with_derived_types = MyType

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

Примеры:

Значение параметра Итоги
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 с заданным полным именем и всем производным от них типам.

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

Нарушение

using System;
using System.DirectoryServices;

public partial class WebForm : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string userName = Request.Params["user"];
        string filter = "(uid=" + userName + ")";  // searching for the user entry

        // In this example, if we send the * character in the user parameter which will
        // result in the filter variable in the code to be initialized with (uid=*).
        // The resulting LDAP statement will make the server return any object that
        // contains a uid attribute.
        DirectorySearcher searcher = new DirectorySearcher(filter);
        SearchResultCollection results = searcher.FindAll();

        // Iterate through each SearchResult in the SearchResultCollection.
        foreach (SearchResult searchResult in results)
        {
            // ...
        }
    }
}
Imports System
Imports System.DirectoryServices

Partial Public Class WebForm
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(send As Object, e As EventArgs)
        Dim userName As String = Me.Request.Params(""user"")
        Dim filter As String = ""(uid="" + userName + "")""    ' searching for the user entry

        ' In this example, if we send the * character in the user parameter which will
        ' result in the filter variable in the code to be initialized with (uid=*).
        ' The resulting LDAP statement will make the server return any object that
        ' contains a uid attribute.
        Dim searcher As DirectorySearcher = new DirectorySearcher(filter)
        Dim results As SearchResultCollection = searcher.FindAll()

        ' Iterate through each SearchResult in the SearchResultCollection.
        For Each searchResult As SearchResult in results
            ' ...
        Next searchResult
    End Sub
End Class