Поделиться через


Аудит зависимостей пакета для уязвимостей безопасности

Сведения об аудите безопасности

Аудит безопасности для диспетчеров пакетов, таких как NuGet, — это процесс, который включает в себя анализ безопасности пакетов, включенных в проект программного обеспечения. Это включает выявление уязвимостей, оценку рисков и рекомендации по улучшению безопасности. Аудит может включать проверку самих пакетов, а также любые зависимости и связанные с ними риски. Цель аудита заключается в выявлении и устранении уязвимостей безопасности, которые могут быть использованы злоумышленниками, например внедрение кода или атаки на межсайтовые сценарии.

Доступность функций

NuGet Пакет SDK для .NET Visual Studio Функция
5.9 Пакет SDK для .NET 5 (5.0.200) Н/П dotnet list package --vulnerable
6.8 Пакет SDK для .NET 8 (8.0.100) Visual Studio 2022 17.8 NuGetAudit для PackageReference
6.10 Н/П Visual Studio 2022 17.10 NuGetAudit для packages.config
6,11 Пакет SDK для .NET 8 (8.0.400) Visual Studio 2022 17.11 NuGetAuditSuppress для PackageReference
6,12 Пакет SDK для .NET 9 (9.0.100) Visual Studio 2022 17.12 Источники аудита. NuGetAuditSuppress для packages.config.
7.0 Пакет SDK для .NET 10 (10.0.100) Visual Studio 2026 Изменения NuGetAuditMode по умолчанию для .NET 10. dotnet package update --vulnerable

Выполнение аудита безопасности с помощью restore

Команда restore автоматически выполняется при выполнении обычной операции пакета, например при загрузке проекта в первый раз, добавлении нового пакета, обновлении версии пакета или удалении пакета из проекта в любимой интегрированной среде разработки. Зависимости проверяются на наличие списка известных уязвимостей, предоставляемых источниками аудита.

  1. В командной строке перейдите в каталог проекта или решения.
  2. Запустите restore с помощью предпочитаемого инструмента (т. е. dotnet, MSBuild, NuGet.exe, VisualStudio и т. д.).
  3. Просмотрите предупреждения и учтите известные уязвимости системы безопасности.

Настройка аудита NuGet

Аудит можно настроить с помощью свойств MSBuild в .csproj файле MSBuild, который оценивается как часть проекта. Рекомендуется настроить аудит на уровне репозитория.

Свойство MSBuild По умолчанию. Возможные значения Примечания.
NuGetAuditMode См. 1 ниже direct и all. Если вы хотите проверить только зависимости верхнего уровня, можно задать значение direct. NuGetAuditMode неприменимо для проектов packages.config.
NuGetAuditLevel Низкий low, moderate, high и critical Минимальный уровень серьезности для отчета. Если вы хотите просмотреть moderate, highи critical рекомендации (исключить low), задайте для значения значение moderate
NuGetAudit правда true и false. Если вы хотите не получать отчеты аудита безопасности, вы можете полностью отказаться от работы, задав значение false
  1. NuGetAuditMode по умолчанию используется all, если проект нацелен на net10.0 или выше. В противном случае NuGetAuditMode используется значение directпо умолчанию. Когда проект использует несколько целевых платформ, и хотя бы для одной целевой платформы выбрано значение all, аудит будет использовать это значение для всех целевых платформ.

Источники аудита

Восстановление скачивает ресурсVulnerabilityInfo для проверки списка пакетов, которые использует каждый проект. Список источников определяется элементом auditSources в NuGet.Config, и предупреждение NU1905 возникает, если любой из источников аудита не предоставляет никаких сведений об уязвимостях. Если auditSources не определен или снят без добавления источников, packageSources будет использоваться и предупреждение NU1905 отключается.

Так как распространенный способ устранения атак на подстановку пакетов заключается в использовании одного источника пакета, который выполняется из nuget.org, чтобы NuGet не использовал nuget.org в качестве источника пакета, источники аудита можно использовать для использования nuget.org (или любого другого источника, предоставляющего сведения об уязвимости), не используя его в качестве источника пакета.

Источником данных для базы данных уязвимостей nuget.org является GitHub Advisory Database. Обратите внимание, что протокол V2 не рекомендуется, поэтому если конфигурация nuget.config по-прежнему использует конечную точку версии 2, необходимо перейти к конечной точке версии 3.

<configuration>
    <auditSources>
        <clear />
        <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    </auditSources>
</configuration>

Примечание. В таблице ниже перечислены функции, поддерживающие источники аудита.

Введено в Вспомогательные источники аудита функций
Пакет SDK NuGet 6.12, .NET 9.0.100 и Visual Studio 2022 17.12 Restore
NuGet 6.14, .NET 9.0.300 SDK dotnet package list --vulnerable
NuGet 7.0 и Visual Studio 2026 Поддержка NuGet AuditSources в пользовательском интерфейсе Диспетчера пакетов Visual Studio

Коды предупреждений

Код предупреждения Причина
NU1900 Ошибка связи с источником пакета при получении сведений об уязвимостях.
NU1901 Пакет с низкой степенью серьезности обнаружен
NU1902 Обнаружен пакет с умеренной серьезностью
NU1903 Пакет с высоким уровнем серьезности обнаружен
NU1904 Пакет с обнаруженным критическим уровнем серьезности
NU1905 Источник аудита не предоставляет базу данных уязвимостей

Вы можете настроить сборку для обработки этих предупреждений как ошибок для обработки предупреждений как ошибок или обрабатывать предупреждения не как ошибки. Например, если вы уже используете <TreatWarningsAsErrors> для обработки всех предупреждений (C#, NuGet, MSBuild и т. д.), их можно использовать <WarningsNotAsErrors>$(WarningsNotAsErrors);NU1901;NU1902;NU1903;NU1904</WarningsNotAsErrors> для предотвращения уязвимостей, обнаруженных в будущем, от нарушения сборки. Кроме того, если вы хотите сохранить низкие и умеренные уязвимости в качестве предупреждений, но обрабатывать высокие и критически важные уязвимости как ошибки, и вы не используете TreatWarningsAsErrors, вы можете использовать <WarningsAsErrors>$(WarningsAsErrors);NU1903;NU1904</WarningsAsErrors>.

Примечание.

Свойства MSBuild для серьезности сообщений, например NoWarn и TreatWarningsAsErrors не поддерживаются для проектов packages.config.

Исключение рекомендаций

Вы можете исключить рекомендации, добавив новый NuGetAuditSuppress элемент MSBuild для каждой рекомендации. Определите NuGetAuditSuppress элемент с метаданными, Include= заданным для URL-адреса рекомендаций, которые вы хотите отключить.

<ItemGroup>
    <NuGetAuditSuppress Include="https://github.com/advisories/XXXX" />
</ItemGroup>

Как и другие свойства конфигурации аудита NuGet, NuGetAuditSuppress элементы можно определить на уровне проекта или репозитория.

NuGetAuditSuppress доступен для проектов PackageReference, начиная с NuGet 6.11, Visual Studio 17.11 и пакета SDK для .NET 8.0.400. Он доступен для пакетов.config из Visual Studio 17.12 и NuGet 6.12.

Когда следует исключить рекомендации

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

Действия при обнаружении пакетов с известными уязвимостями

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

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

Уязвимости пакетов могут быть зарегистрированы как в прямых, так и в транзитивных ссылках на пакет. Действия, которые вы предпринимаете для решения проблемы, могут отличаться из-за этого.

Уязвимости системы безопасности, обнаруженные с обновлениями

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

  • Измените .csproj расположение или другое расположение версии пакета (Directory.Packages.props) с более новой версией, содержащей исправление безопасности.
  • Используйте пользовательский интерфейс диспетчера пакетов NuGet в Visual Studio для обновления отдельного пакета.
  • dotnet package update --vulnerable Выполните команду, чтобы обновить все уязвимые пакеты в проекте до первой версии без известных уязвимостей.
  • Выполните команду dotnet package update или dotnet package add с соответствующим идентификатором пакета, чтобы обновить до последней версии. Используется dotnet add package при использовании .NET 9 или более ранней версии.
  • Используйте сервер Протокола контекста модели NuGet (MCP), который имеет возможность обновлять пакеты в проекте до версий, которые разрешают известные уязвимости. Дополнительные сведения см. в статье об устранении уязвимостей пакетов .

Транзитивные пакеты

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

Например, предположим, что проект ссылается на пакет A. Пакет A имеет зависимость от пакета B, который, в свою очередь, зависит от пакета C. В этом примере мы рассмотрим, что пакет C версии 1.0.0 имеет известную уязвимость, исправленную в версии 2.0.0. Мы рекомендуем сначала попробовать обновить пакет A. Если это не устраняет предупреждение аудита, попробуйте обновить пакет B. Если это не устраняет предупреждение аудита, обновите C напрямую. Чтобы помочь с этим, вам потребуется найти транзитивный путь пакета.

В итоге, если известная уязвимость существует в транзитивных зависимостях пакета верхнего уровня, у вас есть следующие параметры:

  • Проверьте, содержит ли пакет верхнего уровня обновление, которое не имеет транзитивной уязвимости и обновите его.
  • Обновите ближайший пакет из ваших прямых зависимостей, который не содержит уязвимостей.
  • Добавьте фиксированную версию пакета в качестве прямой ссылки на пакет. Примечание. Не забудьте удалить эту ссылку, когда новое обновление версии пакета становится доступным и обязательно сохраните определенные атрибуты для ожидаемого поведения.
  • Используйте централизованное управление пакетами с функцией транзитивного закрепления. Обратите внимание, что если вы упаковаете проект в собственный пакет для совместного использования с другими пользователями, CPM с транзитивным закреплением приведет к тому, что пакеты становятся зависимостями, даже если проект не вызывает API-интерфейсы непосредственно в этом пакете.
  • Отключайте рекомендации до тех пор, пока его не удастся устранить.
  • Отправьте проблему в средство отслеживания пакета верхнего уровня, чтобы запросить обновление.
Поиск пути транзитивного пакета

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

dotnet nuget зачем

В командной строке можно использовать dotnet nuget why команду , чтобы понять, почему транзитивные пакеты включены в граф пакетов проекта.

Dotnet nuget, почему пример

Обозреватель решений Visual Studio

Проекты стилей ПАКЕТА SDK также предоставляют полный граф пакетов в узле зависимостей проекта. Он также доступен для поиска! Разверните параметры поиска и включите "поиск внешних файлов".

Параметры поиска обозревателя решений Visual Studio

Найдите имя пакета, и система отобразит все случаи под узлом 'Зависимости' каждого проекта.

Результаты поиска обозревателя решений Visual Studio

Пользовательский интерфейс диспетчера пакетов NuGet Visual Studio

При просмотре вкладки "Установленные" в пользовательском интерфейсе диспетчера пакетов Visual Studio, когда проект использует PackageReference для управления пакетами, он будет отображать как прямые, так и транзитивные пакеты. В настоящее время это происходит только при управлении пакетами для проекта, а не для решения.

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

Подсказка пользовательского интерфейса диспетчера пакетов Visual Studio

Уязвимости системы безопасности, обнаруженные без обновлений

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

  • Проверьте все факторы, смягчающие факторы, описанные в консультативном отчете.
  • Используйте предлагаемый пакет, если пакет помечен как нерекомендуемый или не рекомендуется.
  • Если пакет открытый код, рассмотрите возможность внесения исправления.
  • Откройте проблему в средство отслеживания проблем пакета.

Проверка факторов устранения рисков

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

Использование предлагаемого пакета

В случае, если для используемого пакета сообщается рекомендации по обеспечению безопасности, и пакет помечен как устаревший или кажется устаревшим, рассмотрите возможность использования любого предлагаемого альтернативного пакета, который автор пакета объявил или пакет, состоящий из аналогичных функций, которые поддерживаются.

Участие в исправлении

Если исправление не существует для рекомендаций по безопасности, может потребоваться предложить изменения, которые устраняют уязвимость в запросе на вытягивание в репозитории пакета открытый код или обратитесь к автору Contact owners через раздел на странице сведений о пакете NuGet.org.

Открытие проблемы

Если вы не хотите исправить уязвимость или не можете обновить или заменить пакет, откройте проблему в средство отслеживания проблем пакета или предпочтительный метод контакта. На NuGet.org вы можете перейти на страницу сведений о пакете и щелкнуть Report package , что поможет вам связаться с автором.

Нет обнаруженных уязвимостей безопасности

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

Выполнение аудита NuGet в CI

Разделение ошибок от предупреждений с помощью выделенного конвейера аудита

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

Как и многие вещи в программировании, существует несколько способов достижения результата. Один из вариантов — рассматривать предупреждения аудита NuGet как ошибки только в конвейере аудита.

<PropertyGroup>
  <NuGetAuditCodes>NU1900;NU1901;NU1902;NU1903;NU1904;NU1905</NuGetAuditCodes>
  <WarningsAsErrors Condition=" '$(AuditPipeline)' == 'true' ">$(WarningsAsErrors);$(NuGetAuditCodes)</WarningsAsErrors>
  <WarningsNotAsErrors Condition=" '$(AuditPipeline)' != 'true' ">$(WarningsNotAsErrors);$(NuGetAuditCodes)</WarningsNotAsErrors>
</PropertyGroup>

Затем в конвейере вы выполняете восстановление, указывая свойство, используемое условием. Например, с помощью синтаксиса GitHub Actions:

- name: Restore with NuGet Auditing
  run: dotnet restore -p:AuditPipeline=true

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

Используя условия, чтобы выборочно заставить предупреждения аудита NuGet приводить к сбою восстановления, можно создать специально выделенный конвейер для проверки пакетов на известные уязвимости, а также предотвратить блокировку исправлений ошибок новыми предупреждениями безопасности в неподходящее время. Сохранение включенных предупреждений аудита NuGet для локальных сборок позволяет разработчикам получать неблокирующие уведомления о новых рекомендациях по безопасности и может поощрять обновление версий пакетов для устранения уязвимостей быстрее, чем ожидание проверки состояния конвейера аудита.

Обеспечение восстановления проверенных проектов

NuGet в MSBuild 17.13 и .NET 9.0.200 добавил результирующие свойства RestoreProjectCount, RestoreSkippedCount и RestoreProjectsAuditedCount в задачу восстановления. Это можно использовать для обеспечения выполнения аудита во время восстановления. Обратите внимание, что эти выходные свойства недоступны при восстановлении статического графа.

Так как MSBuild является языком сценариев, это можно достичь нескольких способов, но также имеет те же ограничения, что и MSBuild. Одним из примеров является создание файла Directory.Solution.target в том же каталоге, что и файл решения, содержимое которого имеет целевой объект, аналогичный приведенному ниже. Обратите внимание, что Directory.Build.props часто используется, но импортируется в проекты. Однако целевой объект восстановления и задача NuGet выполняются на уровне решения, поэтому необходимо находиться в файле расширяемости решения MSBuild, а не в файле проекта или сборки.

<Project>
    <Target Name="AssertRestoreTaskOutputProperties"
            AfterTargets="Restore"
            Condition="'$(CI)' == 'true'">
        <Error
            Condition="'$(RestoreProjectsAuditedCount)' != '$(RestoreProjectCount)'"
            Text=""Restore did not audit every project in the solution. Expected: $(RestoreProjectCount) Found: $(RestoreProjectsAuditedCount)"" />
    </Target>
</Project>

В зависимости от варианта использования, может потребоваться использовать условие '$(RestoreProjectCount)' != '$([MSBuild::Add($(RestoreProjectsAuditedCount), $(RestoreSkippedCount))' в сообщении об ошибке, чтобы учесть проекты, для которых восстановление было пропущено, так как они уже были актуальны. Аналогичным образом подумайте, хотите ли вы, чтобы эта ошибка происходила везде или только в конвейерах CI, а также учтите, какие переменные среды определены в вашей среде CI, и как это может повлиять на условие применения. Как уже упоминалось, так как MSBuild является языком сценариев, вы можете использовать любую из его возможностей для настройки репозитория по вашему усмотрению. Просмотр метапроекта и двоичных журналов MSBuild полезен для разработки и устранения неполадок целевых установок уровня решения.

dotnet list package --vulnerable

dotnet list package --vulnerable имеет аргумент для фильтрации пакетов на основе известных уязвимостей пакетов. Обратите внимание, что --include-transitive это не по умолчанию, поэтому следует включить.