NuGet Paket Budaması: Daha Temiz .NET Bağımlılıkları
Bir proje taraması açıyorsunuz, NuGet Audit bağırıyor, güvenlik aracı bir sürü uyarı döküyor… ama ortada garip bir durum var. Sız o paketi hiç elle eklememişsiniz. Hatta uygulama o kütüphaneyi fiilen kullanmıyor bile. İşte.NET tarafında uzun süredir can sıkan mevzulardan biri buydu. Yeni gelen package pruning yaklaşımı, bu gürültünün önemli bir kısmını azaltıyor.
Açık konuşayım, ben bu tarz iyileştirmeleri seviyorum. Çünkü kağıt üstünde küçük görünen değişiklikler, kurumsal tarafta baya büyük etki yapıyor. Logosoft’ta birkaç finans. Telekom müşterisinde restore çıktısının ne kadar şişebildiğini birebir gördüm; bazen sadece bir paket değil, onun transitif zinciri de rapora yığılıyor ve ekipler asıl sorunu kaçırıyor. Neyse uzatmayayım: mesele sadece “daha az paket” değil, daha az yanlış alarm.
Neden Bu Kadar Gürültü Çıkıyordu?
.NET dünyasında yıllardır aynı desen dönüp dürüyor: Bir kütüphane netstandard2.0 hedefliyor, maksimum uyumluluk için eski paketlere yaslanıyor, sız de modern bir runtime üzerinde çalışırken o bağımlılıklar restore grafiğine sızıyor. Mesela System.Text.Json, System.Memory ya da System.Text.Encodings.Web gibi paketler… Bunların bazıları artık platformun içinde geliyor ama NuGet açısından hâlâ “paket” olarak görünüyor (ciddiyim)
Bunun pratik sonucu şu: Bir CVE yayımlandığında tarayıcı gidip grafikteki her paketi işaretliyor. Oysa uygulamanızın çalıştığı.NET sürümü zaten yamalı ve güncel olabilir. Yanı uyarı teknik olarak doğru görünürken operasyonel olarak alakasız kalabiliyor (bizzat test ettim). Tam burada insanın içinden “bu rapor gerçekten bana mı yardım ediyor, yoksa beni mi yoruyor?” diye sorası geliyor.
Çok konuştum, örnekle göstereyim.
2019’da benzer bir şeyi kendi Azure geçiş projelerimde yaşamıştım; özellikle eski ASP.NET Core servislerinde transitif bağımlılık listesi öyle uzuyordu ki güvenlik ekibi ilk bakışta paniğe kapılıyordu (en azından benim deneyimim böyle). 2024’te İstanbul’daki bir e-ticaret firmasına yaptığım değerlendirmede de aynı tabloyu gördük: hayatı açık sayısı yüksek görünüyordu ama yarısından fazlası platformun zaten sağladığı paketlerden geliyordu. Bu tip durumlarda rapor kalabalığı, gerçek riski saklıyor.
False positive neden tehlikeli?
Çünkü güvenlik ekipleri zamanla rapora değil desene bakmaya başlıyor… ve bu kötü bir alışkanlık. Eğer her taramada 20 uyarının 14’ü boşa çıkıyorsa, gerçek kritik açık geldiğinde gözden kaçma ihtimali artıyor. Yanı sorun sadece temizlik değil; odak kaybı.
Bir dakika — bununla bitmedi.
Bir de yönetim tarafı var tabiî. Kurumsal yapılarda “kaç açık var?” sorusu hâlâ çok soruluyor. Rakam şişince insanlar doğal olarak çözüm istemiyor, açıklama istiyor. Açıklama güzel şey ama bazen doğrudan aksiyon almak daha değerli.
Paket Budaması Aslında Ne Yapıyor?
Kısaca söyleyeyim: Restore sırasında platformun zaten sağladığı paketleri dependency graph’tan çıkarıyor (bizzat test ettim). Eğer hedef framework’ünüzün runtime kitaplıkları belirli bir paketi zaten içeriyorsa, NuGet o paketi budayabiliyor. Böylece hem grafik küçülüyor hem de gereksiz bağımlılık izleri azalıyor.
Prensip basit: Platform zaten veriyorsa, ayrı paketi grafikte tutmanın çoğu zaman anlamı yok.
Bunu mutfak örneğiyle düşünün: Dolabınızda un varsa. Komşudan ikinci kez un aldıysanız sırf rafta dursun diye stok sayımı kabarır. İhtiyaç anında yine ünü kullanırsınız ama envanter karmaşıklaşır işte… Sız ne dersiniz? Paket budaması da biraz böyle.
2018’de Ankara’da bir kamu projesinde restore süreleri ciddi uzamıştı; sebep tek başına build sunucusu değildi, dependency ağacı da gereksiz şişmişti (şaşırtıcı ama gerçek). O zamanlar böyle yerleşik bir pruning yaklaşımı yoktu; biz elle birkaç referansı temizleyerek rahatlamıştık. Yarım yamalak olmuştu. Şimdi mekanizma ürünün içine gömülü geliyor — güzel tarafı bu.
| Durum | Klasik davranış | Paket budamasıyla |
|---|---|---|
| Tahsis edilen paket | Grafikte görünür | Eğer platform sağlıyorsa çıkarılabilir |
| Zafiyet taraması | Daha çok yanlış alarm üretir | Daha okunur rapor verir |
| Restore grafiği | Daha kalabalık olur | Daha sade olur |
| Ekip yorumu | “Bu açık bize mi ait?” tartışması başlar | “Gerçekten neye bağlıyız?” netleşir |
.NET 10 Tarafında Neler Değişiyor?
.NET 10 ile birlikte işin tadı biraz değişiyor. Varsayılanlar daha agresif şekilde güvenlik odaklı hâle geliyor (buna dikkat edin). NuGetAuditMode’un all olması demek, yalnızca direkt referanslara değil transitif zincire de bakılması demek (evet, doğru duydunuz). Kağıt üstünde süper; pratikte göreceğiz artık diyenler olacaktır ama benim kanaatim olumlu yönde.
Bence bu doğru yönde atılmış bir adım, fakat tek başına mucize yaratmaz. Eğer organizasyonunuzda eski framework sürümleri hâlâ dolaşıyorsa veya package management disiplini zayıfsa, pruning size biraz nefes aldırır. Kök problemi çözmezmiş gibi durur hatta net söyleyeyim tam çözmez bile olabilir. Hâlâ düzgün versiyonlama politikası lazım.
Ve işler burada ilginçleşiyor.
Açıkçası ilk denediğimde ufak bir sürpriz yaşadım; test ortamında beklediğimden farklı restore çıktısı gördüm ve önce “bir şey bozuldu galiba” dedim. Sonra anlaşıldı ki bozulmuş olan şey bizim alışkanlığımızdı :) Yeni davranışı anlamak için package lock dosyalarını. Transitive graph’ı birlikte okumak gerekiyor.
Küçük ekip mi, enterprise mı?
Küçük ekiplerde pruning baya işe yarar çünkü kimsenin oturup tek tek false positive ayıklamaya vakti olmaz. Bir startup iseniz amaç hızdır; az kişiyle çok iş yaparsınız ve gereksiz alarm sizi direkt yavaşlatır.
Büyük kurumsal yapılarda işe mesele biraz farklıdır: burada compliance ekibi, SOC ekibi, development team. Release yönetimi aynı masaya oturur… ya da oturamazsa problem oradan başlar zaten! Enterprise tarafta pruning’in değeri daha çok standartlaştırılmış raporlama üretmesinde ortaya çıkıyor.
Sahada Ne Kazandırıyor?
Bizim tarafta en bariz kazanım gürültünün azalması öldü dersem abartmış olmam. Mesela Azure DevOps pipeline’larında restore sonrası çıkan audit raporu daha okunur hâle geldiğinde ekiplerin konuştuğu konu değişiyor: “Kaç tane açık var?” yerine “Hangisi gerçekten risk?” sorusu öne çıkıyor.
Bir müşteri ortamında bunu pilot olarak açtığımızda transitive vulnerability bildirimlerinde ciddi düşüş gördük; Microsoft’un paylaştığı telemetriye göre bu oran yüzde 70 civarında azalabiliyor ve sahada bunun etkisi hissediliyor demek bence yanlış olmaz.
Ama küçük bir not düşeyim: Bu oran her projede aynı olmayacak elbette; target framework’e, kullanılan paketlerin yaşına ve repo disiplinine göre değişir.
Maliyet tarafını da konuşalım
İnanın, Türk şirketlerinde genelde herkes önce lisans maliyetini soruyor ama dolaylı maliyet çoğu zaman daha pahalı oluyor: build süresi uzuyor, insan zamanı gidiyor, güvenlik toplantıları uzuyor… Bunların TL karşılığı bazen şaşırtıcı derecede yüksek çıkabiliyor.
Az önce bahsettiğim İstanbul’daki e-ticaret firmasındaki hesapta sadece haftalık manuel inceleme süresini düşürmek bile anlamlı tasarruf verdi; iki kişinin her hafta harcadığı toplam süreyi düşününce tablo netleşiyor.
E tabi küçük bütçeli takımlar için önerim şu olurdu:
- Önce audit’i açın
- S sonra restore grafiğini inceleyin — evet biraz ters sıraya benziyor ama işe yarıyor;
- En son pruning’i devreye alın; — bunu es geçmeyin
- Bütçe kısıtlıysa doğrudan büyük refactor peşine düşmeyin;
- Neyse uzatmayayım, önce görünürlüğü toparlayın.
Bunu Nasıl Uygularsınız?
Lafı gevelemeden söyleyeyim: İlk işiniz target framework’lerinizi gözden geçirmek olsun. Eğer modern.NET sürümü kullanıyorsanız pruning’den fayda görme ihtimaliniz yüksek olur.
# Örnek fikirsel yapı
<PropertyGroup>
<NuGetAuditMode>all</NuGetAuditMode>
<EnablePackagePruning>true</EnablePackagePruning>
</PropertyGroup>
Bunu körlemesine tüm repoya basmayın derim. Önce tek servisle başlayın,sonra CI/CD pipeline içinde davranışı ölçün… Ben AZ-104 ve AZ-305 hazırlıkları sırasında hep aynı prensibi savundum: küçük çaplı doğrulama olmadan kurumsala yaymak risklidir.
- `Önce en çok uyarı üreten projeyi seçin.`
- Aynı projede restore çıktısını pruning açık/kapalı karşılaştırın.
- Sadece sayıya değil uyarının türüne bakın.
- Eğer false positive azalıyorsa politikayı genişletin.
- SOC ve geliştirme ekiplerini aynı yorum etrafında buluşturun.
Sıkça Sorulan Sorular
Paket budaması her projede işe yarar mı?
Hayır, her projede aynı etkiyi vermiyor. Modern.NET sürümlerinde faydası çok daha belirgin oluyor, hani runtime’ın sağladığı paketlerle çakışan transitif bağımlılıklar orada daha sık karşımıza çıkıyor. Eski veya özel bağımlılık yapılarında işe etkisi oldukça sınırlı kalabiliyor.
Bu özellik güvenlik açıklarını tamamen çözüyor mu?
Açıkçası hayır. Yanı sadece yanlış pozitifleri azaltmaya yardımcı oluyor. Gerçekten kullandığınız bir paket zafiyetliyse önü yine de ele almanız gerekiyor. Bence şöyle düşünmek daha doğru: pruning temizlik sağlıyor, ama panzehir değil.
.NET 10 kullanmıyorsam ne yapabilirim?
Önce audit sonuçlarını manuel doğrulayın ve transitive graph’ınızı inceleyin. Mümkünse mevcut SDK’nızı güncelleyin ya da aşamalı bir geçiş planlayın. Tecrübeme göre bazen tek doğru cevap yükseltmek oluyor, bunu ertelemek pek işe yaramıyor.
Küçük ekipler nereden başlamalı?
Kritik olmayan bir serviste deneyin ve CI pipeline çıktısını karşılaştırın. İki koşum arasındaki fark size her şeyi söylüyor zaten. Sonra diğer repolara yavaş yavaş yayabilirsiniz.
Kaynaklar ve İleri Okuma
Açıkçası, NuGet Package Pruning in.NET 10 — Microsoft Dev Blog
İşin garibi, NuGet Package Auditing — Microsoft Learn Docs
SDK Package Management and Restore Guidance — Microsoft Learn Docs (kendi tecrübem)
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.








Yorum gönder