Geliştirici Araçları

.NET 10’da NuGet Package Pruning: Sahadan Notlar

Geçen hafta bir müşteride tam da şu sahne öldü: Güvenlik ekibi, üretime çıkacak bir.NET servisi için hazırlanmış vulnerability tarama raporunu masaya bıraktı. Sayfa sayfa System.Text.Json, System.Text.Encodings.Web, System.Memory… Listede 14 tane “yüksek” seviye uyarı vardı. Geliştirici ekip şaşkındı — “Biz bu paketlerin hiçbirini eklemedik ki?” Güvenlik tarafı da haklı olarak gerildi — “O zaman neden raporda görünüyor?”

İşte bu çatışmayı yumuşatmak için.NET 10 tarafında sessiz sedasız ama bence baya hayatı bir değişiklik geldi: NuGet Package Pruning. Lafı gevelemeden söyleyeyim — telemetri verilerine göre, default’larla gelen projelerde transitive vulnerability raporları %70 azalmış. Ben ilk duyduğumda “hadi canım” dedim. Sonra kendi test projelerimde denedim, valla öyle çıktı.

Problem Aslında Ne? Hadi En Baştan Anlatayım

Bence, Bakın şimdi,.NET ekosisteminin eski bir alışkanlığı var. netstandard2.0 hedefleyen yüzlerce kütüphane nuget.org’da duruyor. Bunlar hâlâ System.Memory, System.Text.Json gıbı paketlere yaslanıyor. Halbuki bu paketler artık .NET (belki yanılıyorum ama) Runtime Libraries‘in bir parçası. Yanı siz.NET 8 ya da.NET 10 üzerinde koşuyorsanız, runtime zaten o kodu getiriyor; ayrıca dışarıdan çekmeye çoğu zaman gerek kalmıyor.

Kendi deneyimimden konuşuyorum, Ama NuGet bunu uzun süre çok umursamadı gıbı davrandı. Ya da biliyordu da, kenarda bekledi; nasıl desem, biraz pasif kaldı. Restore sırasında o eski paket referansını da grafa ekliyordu. Sonuç?

  • Restore grafı şişiyor
  • Eski paket versiyonları için CVE çıktığında, uygulama aslında o kodu kullanmıyor olsa bile uyarı alıyorsunuz
  • Güvenlik ekipleriyle gereksiz toplantılar yapıyorsunuz (en pahalı maliyet bence bu)

Bir örnek vereyim. System.IO.Pipelines başlangıçta bağımsız bir NuGet paketiydi. Sonra.NET platformunun parçasına dönüştü. Ama nuget.org’daki eski paket hâlâ orada duruyor. Hâlâ resolve edilebiliyor. CVE çıktığında yine raporlara düşebiliyor. Oysa uygulamanız o paketin tek satırını bile kullanmıyor; runtime’ın getirdiği sürüm iş görüyor.

Yıllardır güvenlik denetimlerinde gördüğüm en yaygın “false positive” kaynaklarından biri buydu. Bir CISO’ya “merak etmeyin, bu paket aslında kullanılmıyor” demek… eh, pek de ikna edici ölmüyor. Kanıt lazım oluyor. Pruning artık o kanıtı altyapının içinden veriyor.

Package Pruning Tam Olarak Nasıl Çalışıyor?

Mantık basit gıbı duruyor ama işin içinde güzel bir detay var..NET SDK, her target framework için “bu framework hangı paketleri ve hangı en yüksek sürümleri zaten içeriyor” diye bir liste tutuyor. Restore sırasında NuGet, transitive bir bağımlılığı bu listedeki bir paketle eşleştirirse ve versiyon da framework’ün sağladığı sürümün altında ya da eşitse, o paketi grafdan tamamen çıkarıyor.

Yanı şöyle düşünün: net10.0 hedefliyorsunuz. Bir kütüphane transitive olarak System.Text.Json 8.0.0‘ı çekiyor..NET 10 runtime’ı. Daha yeni bir sürümü getirdiği için NuGet diyor ki “kardeşim, ben bunu zaten getiriyorum, sen tekrar ekleme”. Ve eklemiyor.

Ama dikkat — eğer transitive dependency framework’ün sağladığından daha yüksek bir sürüm istiyorsa (mesela net8.0 hedefliyor. System.Text.Json 9.0.0 gerekiyor), pruning devreye girmiyor. Çünkü orada gerçekten daha yeni bir şey lazım oluyor. Bu ayrıntı önemli; ilk bakışta “her şeyi siliyor mu acaba?” diye düşündüm ben de biraz. Yok, öyle kaba saba çalışmıyor.

Default Davranış.NET 10’da Ne Öldü?

Burada değişiklik netleşiyor işte..NET 10 ile birlikte iki şey otomatik açık geliyor:

  • NuGetAuditMode = all: Sadece direct değil, transitive bağımlılıklar da denetleniyor
  • Package Pruning aktif: Platform-provided paketler graftan çıkarılıyor

Bu ikisi birlikte çalışınca o %70 azalma ortaya çıkıyor diyebiliriz (en azından benim deneyimim böyle). Audit modunu açıyorsunuz ama gereksiz gürültü de ayıklanıyor. Açık konuşayım, fena denge değil.

Peki Bir Projede Nasıl Görünüyor? Mini Bir Örnek Verelim

Böyle basit bir csproj düşünün: Copilot CLI Uzaktan Kontrol: Telefondan Terminal Yönetimi yazımızda bu konuya da değinmiştik.

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<!-- Bu zaten default ama görmek için yazıyorum -->
<RestoreEnablePackagePruning>true</RestoreEnablePackagePruning>
<NuGetAuditMode>all</NuGetAuditMode>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SomeLegacyLib" Version="2.1.0" />
</ItemGroup>
</Project>

Diyelim SomeLegacyLib, netstandard2.0 hedefliyor ve şunları transitive çekiyor: Daha fazla bilgi için Visual Studio Agent Skills: Copilot’a Takımı Öğretmek yazımıza bakabilirsiniz. Cosmos Conf 2026: AI Çağında Veritabanı Nereye Gidiyor? yazımızda bu konuya da değinmiştik.

Transitive Paket İstenen Versiyon net10.0’da Durumu Sonuç
System.Text.Json 6.0.0 Daha yeni runtime var ✂️ Prune edildi
System.Memory 4.5.5 Daha yeni runtime var ✂️ Prune edildi
System.Buffers 4.5.1 Daha yeni runtime var ✂️ Prune edildi
Newtonsoft.Json 13.0.1 Platform paketi değil ✅ Korundu
}

Kısacası restore graph’ınızda artık System.Text.Json 6.0.0 ‘ diye bir şey görünmüyor diyebilirsiniz — burada küçük yazım kazaları ölür ya, asıl fikir şu: CVE çıksa bile sızı ilgilendirmiyor, çünkü siz önü kullanmıyorsunuz zaten.

Türkiye’deki Kurumsal Müşteriler Açısından Ne Anlama Geliyor?

Burası benim için ayrı ilginç geliyor — çünkü Türkiye’de özellikle finans, kamu. Telekom tarafındaki ekiplerle konuşurken aynı duvara çarpıyoruz: compliance theatre. Yanı ortada gerçek bir güvenlik problemi yokken “raporda kırmızı görünüyor, bunu kapatalım” baskısı başlıyor.

Pruning bunu ciddi ölçüde azaltacak gıbı duruyor.Ama sadece.NET 10’a geçen projelerde.Tabii burada Türkiye’nın klasik ikilemi var: Kurumsal projelerin çoğu hâlâ.NET 6 ya da.NET 8 üstünde.Durum böyle olunca özelliği kullanmak istiyorsanız upgrade gerekiyor —. Kurumsal yapılarda bu karar hiç hafif alınmıyor. Daha fazla bilgi için Copilot Spaces API GA Oldu: Otomasyonun Kapısı Açıldı yazımıza bakabilirsiniz.

Bence eğer.NET 8 LTS’deyseniz. Şirket içinde “audit gürültüsü” gerçekten can sıkmaya başladıysa,.NET 10’a geçişi safety ROI argümanıyla anlatmaya çalışın.Bu sadece teknik terfi değil; operasyonel yükü de azaltabiliyor.Sprintlerde audit-fix işlerine kaç adam-gün gittiğini hesaplayın — şaşırabilirsiniz.

Küçük Ekip mi Büyük Kurum mu?

Küçük bir ekipseniz, mesela üç-beş kişilik startup, derdiniz başka oluyor.Sizin için pruning’in en bariz faydası restore süresi ve build hızı.Daha az paket = daha hızlı CI.Bunu hemen hissedersiniz.

İşin garibi, Enterprise tarafındaysanız —. Yüzlerce mikroservis, merkezî güvenlik ekibi, SOC2 ya da ISO 27001 denetimleri varsa — sizin için fayda başka yerde ortaya çıkıyor.Dashboard’lardaki alarmların azalması gerçek riskleri daha rahat görmenizi sağlıyor.MAESTRO ile Microsoft SQL: Agentic AI Güvenliği yazımda da benzer noktaya değinmiştim; gürültü azalınca sinyal daha net kalıyor.

Peki Geçişte Karşılaşacağınız Olası Problemler Neler?

Açık konuşayım, her şey süt liman değil.Pruning’i ilk denediğimde test projesinde şöyle garip bir durumla karşılaştım: Bir kütüphane, runtime’ın getirdiğiSystem.Text.Json<' / code>'dan daha eski bir API kullanıyordu.Eski paket prune edilince runtime'ın yeni sürümü devreye girdi ve... çalışmadı.Arada property ismi değişmişti.

Şimdi gelelim işin can alıcı noktasına.

Çözüm ne? O kütüphaneyi güncellemek ya da explicit olarakPackageReference ile eski paketi geri eklemek.Ben ikinci yolu ancak çok kritik durumlarda öneririm; çünkü sonra yeniden audit gürültüsüne dönüyorsunuz. Bu konuyla ilgili NL2SQL Gerçekten İşe Yarıyor mu? SQL MCP Server Notları yazımıza da göz atmanızı tavsiye ederim.

💡 Bilgi: Eğer bir paketin prune edilmesini engellemek istiyorsanız, csproj’unuza<PrunePackageReference> ile manuel müdahale edebilirsiniz.Ama bunu yapmadan önce kütüphaneyi güncel sürüme taşımayı deneyin — uzun vadede daha temiz çözüm bu.

Bir de şu var — bazı eski analyzer’lar veya source generator’lar paketin fiziksel olarak grafda olmasını bekleyebiliyor.Nadir görülüyor. Denk gelirseniz hemen panik yapmayın; debug edilebilir bir durum genelde.

Peki Pratik Geçişte Ne Yapmalısınız?

Denemek istiyorsanız, ilk iş olarak şunları yapın:

  1. Bir test branch’i açın .Production’ı doğrudan deneme tahtası yapmayın.
  2. global.json‘ dosyanızı.NET 10 SDK’ya yükseltin.
  3. TargetFramework‘ünet10..n/a

    Sıkça Sorulan Sorular

    NuGet Package Pruning.NET 10'dan eski sürümlerde çalışıyor mu?

    Aslında pruning özelliği kısıtlı olarak.NET 9 SDK ile gelmişti, ama default kapalıydı ve manuel açman gerekiyordu..NET 10 ile birlikte hem default açık hale geldi hem de logic olgunlaştı. Yani bence gerçek anlamda "kullanılabilir" durum.NET 10 ile başlıyor.

    Pruning paketi gerçekten siliyor mu, yoksa sadece raporlardan mı gizliyor?

    Gerçekten restore graph'tan çıkarıyor. Hani obj/project.assets.json dosyasında o paket artık yok. Bu sadece kozmetik bir değişiklik değil — derleme zamanında o paketin assembly'leri yüklenmiyor, runtime'daki versiyon kullanılıyor. Açıkçası bu yüzden gerçek anlamda güvenli bir azaltma diyebiliriz.

    Bazı paketlerin prune edilmesini engelleyebilir miyim?

    Şöyle ki, Evet. csproj dosyasında <PrunePackageReference Include="PaketAdı" /> ile manuel kontrol yapabilirsin. Ama bence bunu istisna olarak kullanmak gerekiyor; her override eklediğinde audit raporlarında o paketin geri döneceğini unutma.

    NuGetAuditMode'u "all" yerine "direct" yaparsam ne oluyor?

    Sadece direct — yani senin açıkça eklediğin — paketler için audit yapılıyor, transitive'ler atlanıyor. Bu güvenlik açısından pek önerilmez, çünkü gerçek vulnerability'ler genellikle transitive'lerde çıkıyor. Mesela eski default davranış buydu..NET 10 ile "all" geldi ve tecrübeme göre doğru karar bu.

    Eski proje şablonlarımı dönüştürmem gerekiyor mu?

    Hayır. csproj formatında herhangi bir değişiklik gerekmiyor. Sadece TargetFrameworknet10.0'a çekmen ve.NET 10 SDK kullanman yeterli. Pruning ve audit otomatik devreye giriyor. Aslında manuel override istemiyorsan hiçbir şey eklemeye gerek yok — sıfır konfigürasyonla çalışıyor.

    Kaynaklar ve İleri Okuma

    Şöyle söyleyeyim, NuGet Package Pruning: Cleaner Dependencies and Actionable Vulnerability Reports (Microsoft.NET Blog)

    İnanın, NuGet Auditing Packages — Resmi Microsoft Dokümantasyonu

    What's New in.NET 10 — Microsoft Learn

    NuGet/Home GitHub Repository — İlgili Issue ve Discussion'lar

Aşkın KILIÇ

20+ yıl deneyimli Azure Solutions Architect. Microsoft sertifikalı bulut mimari ve DevOps danışmanı. Azure, yapay zekâ ve bulut teknolojileri üzerine Türkçe teknik içerikler üretiyor.

AZ-305AZ-104AZ-500AZ-400DP-203AI-102

Bu içerik işinize yaradı mı?

Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.

← Onceki Yazi
Copilot CLI Uzaktan Kontrol: Telefondan Terminal Yönetimi
Sonraki Yazi →
C++ Projelerinde PackageReference: NuGet Yeni Dönem

Yorum Yaz

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

İçindekiler
← Copilot CLI Uzaktan Kontrol: T...
C++ Projelerinde PackageRefere... →