O Pruning de Pacotes NuGet Está Ativado por Padrão no .NET 10
O pruning de pacotes NuGet chegou ativado por padrão para projetos net10.0, cortando os relatórios de vulnerabilidades transitivas em 70% e os tempos de restore em até 50%.
Nikolche Kolev anunciou que o pruning de pacotes NuGet está habilitado por padrão para qualquer projeto que tenha como alvo net10.0 ou posterior. A mudança vem no SDK do .NET 10 e redefine um padrão que vinha causando silenciosamente saída ruidosa em dotnet list package --vulnerable há anos: as bibliotecas do runtime já estão no framework compartilhado, então listá-las novamente como dependências NuGet só cria CVEs fantasmas.
O que o pruning realmente remove
O SDK do .NET inclui um manifesto por target framework dos pacotes que o runtime já fornece, junto com a versão mais alta que cada framework disponibiliza. Durante o restore, o NuGet descarta qualquer pacote transitivo cuja versão esteja igual ou abaixo da do runtime. Referências diretas não são deletadas, mas são reescritas com PrivateAssets='all' e IncludeAssets='none' para que a cópia do runtime vença, e o NuGet emite o novo aviso NU1510 quando a referência é completamente redundante.
O blog cita dois números concretos: 70% menos relatórios de vulnerabilidades transitivas para projetos com os novos padrões, e até 50% menos tempo de restore por projeto assim que o grafo para de perseguir pacotes que o runtime já possui.
O que está ativado por padrão
Em um projeto net10.0, o SDK agora se comporta como se você tivesse escrito:
<PropertyGroup>
<RestoreEnablePackagePruning>true</RestoreEnablePackagePruning>
<NuGetAuditMode>all</NuGetAuditMode>
</PropertyGroup>
NuGetAuditMode=all também muda de direct para all, então o conjunto transitivo restante continua sendo auditado. Pruning e auditoria foram desenhados para se compor: o pruning reduz o grafo ao que de fato é enviado em cima do runtime, e a auditoria roda sobre esse grafo menor.
Em um projeto multi-target, se algum TFM for net10.0 ou posterior, o pruning é aplicado a cada TFM do projeto. Isso evita a surpresa de uma cabeça fazer restore de forma diferente da outra silenciosamente.
Um antes / depois concreto
Um padrão comum é um aplicativo de console que puxa Microsoft.Extensions.AI e NuGet.Protocol. No .NET 9 você veria System.Formats.Asn1 6.0.0 aparecer na saída de auditoria através de um caminho transitivo profundo, mesmo que net10.0 envie um System.Formats.Asn1 mais novo no framework compartilhado. Depois de atualizar o TFM:
<TargetFramework>net10.0</TargetFramework>
System.Formats.Asn1, System.Diagnostics.DiagnosticSource, System.Text.Json e System.Threading.Channels desaparecem do grafo resolvido. Suas entradas de CVE param de aparecer em dotnet list package --vulnerable porque, em primeiro lugar, nunca seriam carregadas em tempo de execução.
Desativando
As duas válvulas de escape existem:
<PropertyGroup>
<RestoreEnablePackagePruning>false</RestoreEnablePackagePruning>
<NuGetAuditMode>direct</NuGetAuditMode>
</PropertyGroup>
Você faria isso em uma biblioteca que genuinamente precisa enviar seu próprio System.Text.Json para consumidores de versões anteriores, ou em um job de CI que ainda tem ferramentas presas a um SDK pré-10 lendo o lock file.
Se você vinha carregando <NoWarn>NU1903;NU1904</NoWarn> para silenciar avisos de vulnerabilidades transitivas em pacotes do framework compartilhado, esta é a versão em que dá para apagar. Suba o TFM, rode restore uma vez, e veja se o relatório de auditoria encolheu.
Comments
Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.