Start Debugging

Очистка пакетов NuGet включена по умолчанию в .NET 10

Очистка пакетов NuGet поставляется включённой по умолчанию для проектов net10.0, сокращая отчёты о транзитивных уязвимостях на 70% и время restore до 50%.

Никольче Колев объявил, что очистка пакетов NuGet включена по умолчанию для любого проекта, нацеленного на net10.0 или новее. Изменение поставляется в .NET 10 SDK и сбрасывает значение по умолчанию, которое годами тихо вызывало шумный вывод dotnet list package --vulnerable: библиотеки среды выполнения уже находятся в общем фреймворке, поэтому повторное перечисление их как зависимостей NuGet лишь создаёт фантомные CVE.

Что именно удаляет очистка

.NET SDK поставляется с манифестом для каждого target framework, содержащим пакеты, которые уже предоставляет среда выполнения, вместе с самой высокой версией, поставляемой каждым фреймворком. Во время restore NuGet отбрасывает любой транзитивный пакет, версия которого равна или ниже версии среды выполнения. Прямые ссылки не удаляются, но переписываются с PrivateAssets='all' и IncludeAssets='none', чтобы выиграла копия среды выполнения, а NuGet выдаёт новое предупреждение NU1510, когда ссылка полностью избыточна.

Блог приводит две конкретные цифры: на 70% меньше отчётов о транзитивных уязвимостях для проектов с новыми значениями по умолчанию и снижение времени restore до 50% на проект, как только граф перестаёт гоняться за пакетами, которыми среда выполнения уже владеет.

Что включено по умолчанию

В проекте net10.0 SDK теперь ведёт себя так, как если бы вы написали:

<PropertyGroup>
  <RestoreEnablePackagePruning>true</RestoreEnablePackagePruning>
  <NuGetAuditMode>all</NuGetAuditMode>
</PropertyGroup>

NuGetAuditMode=all также переключается с direct на all, поэтому оставшееся транзитивное множество по-прежнему проходит аудит. Очистка и аудит спроектированы так, чтобы дополнять друг друга: очистка сокращает граф до того, что действительно поставляется поверх среды выполнения, а аудит работает с этим уменьшенным графом.

В мультицелевом проекте, если хотя бы один TFM это net10.0 или новее, очистка применяется ко всем TFM проекта. Это устраняет ситуацию, когда одна цель тихо делает restore иначе, чем другая.

Конкретное “до и после”

Распространённый сценарий это консольное приложение, тянущее Microsoft.Extensions.AI и NuGet.Protocol. На .NET 9 вы увидели бы, как System.Formats.Asn1 6.0.0 всплывает в выводе аудита через глубокий транзитивный путь, хотя net10.0 поставляет более новый System.Formats.Asn1 в общем фреймворке. После повышения TFM:

<TargetFramework>net10.0</TargetFramework>

System.Formats.Asn1, System.Diagnostics.DiagnosticSource, System.Text.Json и System.Threading.Channels исчезают из разрешённого графа. Их записи CVE перестают появляться в dotnet list package --vulnerable, потому что они и не были бы загружены во время выполнения.

Отключение

Оба обходных пути существуют:

<PropertyGroup>
  <RestoreEnablePackagePruning>false</RestoreEnablePackagePruning>
  <NuGetAuditMode>direct</NuGetAuditMode>
</PropertyGroup>

Так стоит поступить в библиотеке, которой действительно нужно поставлять собственный System.Text.Json для потребителей более ранних версий, или в CI-задаче, у которой инструменты до сих пор закреплены на SDK до версии 10 и читают lock-файл.

Если вы носили с собой <NoWarn>NU1903;NU1904</NoWarn>, чтобы заглушить предупреждения о транзитивных уязвимостях в пакетах общего фреймворка, это тот релиз, в котором эту строку можно удалить. Поднимите TFM, выполните restore один раз и проверьте, насколько сократился отчёт аудита.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад