Herkes Neden Bağımlılık Cooldown’u Kullanmalı
(blog.yossarian.net)- Bağımlılık cooldown’u (dependency cooldown), açık kaynak tedarik zinciri saldırılarının büyük bölümünü hafifletebilen basit ve etkili bir güvenlik tekniğidir
- Saldırganlar genellikle popüler açık kaynak projeleri ele geçirip kötü amaçlı kod dağıtır, ancak çoğu saldırının maruz kalma süresi bir haftadan kısadır
- Yeni bir sürüm yayımlandıktan sonra belirli bir süre (ör. 7 gün) bekleyen bir cooldown ayarlanırsa, otomatik güncellemelerden kaynaklanan bulaşma riski büyük ölçüde azaltılabilir
- Dependabot, Renovate, pnpm gibi araçlar zaten cooldown özelliğini yerleşik olarak destekler; yapılandırması kolaydır ve ek maliyet gerektirmez
- Cooldown’un paket yöneticisi seviyesinde varsayılan olarak sunulması, tedarik zinciri güvenliğinin güçlenmesine ve gereksiz alarmların azalmasına katkı sağlayabilir
Tedarik zinciri saldırılarının yapısı ve sorunları
- Çoğu tedarik zinciri saldırısı (supply chain attack) aynı deseni izler
- Saldırgan, popüler bir açık kaynak projesine kimlik bilgisi hırsızlığı veya CI/CD açığı üzerinden erişim sağlar
- Kötü amaçlı değişiklikleri dağıtım kanalına (PyPI, npm vb.) yükler
- Otomatik güncellemeler veya yetersiz sürüm sabitleme nedeniyle kullanıcılar enfekte sürümü kurar
- Güvenlik sağlayıcıları bunu tespit edip uyarı verir, ardından paket deposu ilgili sürümü kaldırır
- (1) ile (2) adımları arasındaki süre uzun olabilir, ancak (2) ile (5) arasındaki süreç saatler ya da birkaç gün içinde tamamlandığı için saldırganın etkin olduğu süre kısadır
- Son 18 aydaki başlıca örneklerde saldırı fırsatı penceresi (window of opportunity)
- xz-utils: yaklaşık 5 hafta
- Ultralytics: 12 saat (1. aşama), 1 saat (2. aşama)
- tj-actions: 3 gün
- chalk: 12 saatten az
- Nx: 4 saat
- rspack: 1 saat
- num2words: 12 saatten az
- Kong Ingress Controller: yaklaşık 10 gün
- web3.js: 5 saat
- Bunların 8’inde saldırı süresi 1 haftadan kısaydı ve çoğu cooldown ile engellenebilirdi
Cooldown kavramı ve etkisi
- Cooldown, yeni bir bağımlılık yayımlandıktan sonra belirli bir süre kullanılmasını geciktirme yöntemidir
- Bu süre içinde güvenlik sağlayıcıları sürümün kötü amaçlı olup olmadığını tespit edebilir
- Avantajları
- Ampirik olarak etkilidir ve büyük çaplı saldırıların çoğunu engeller
- Uygulaması çok basittir ve çoğu araçta ücretsiz olarak yapılandırılabilir
- Dependabot örneği
version: 2 - package-ecosystem: github-actions directory: / schedule: interval: weekly cooldown: default-days: 7 - Güvenlik sağlayıcılarının olumlu davranmasını teşvik eder: aşırı alarm veya tanıtım yerine hızlı tespiti önceliklendirmelerini sağlar
Sonuç ve öneriler
- 10 saldırının 8’i 1 hafta veya daha kısa sürdü; 7 günlük cooldown bunların çoğunu engelleyebilir
- 14 günlük cooldown uygulanırsa xz-utils dışındaki tüm örnekler savunulabilir
- Cooldown mükemmel bir çözüm değildir, ancak maruz kalma riskini %80–90 azaltan basit bir yöntemdir
- Dependabot ve Renovate’e ek olarak, paket yöneticilerinin de cooldown’u yerleşik olarak desteklemesi için geliştirme yapılmalıdır
- Tedarik zinciri güvenliği yalnızca teknik bir sorun değil, toplumsal güven yapısının da bir meselesidir; ancak cooldown pratik bir hafifletme yöntemi olarak yararlıdır
3 yorum
Aslında bir sorun yoksa, sırf güncelleme yapmak yerine hiç güncellememek daha iyi gibi geliyor.
Önceki sürümden büyük ölçüde farklı olmayan yeni bir sürümü, riski göze alarak mutlaka uygulamak gerekir mi.
Hacker News görüşü
İnsanlar hemen güncellemezlerse kritik güvenlik açıklarına maruz kalacaklarından endişe ediyor, ama pratikte çoğu durumda böyle değil
Birçok yazılım sürekli dağıtımla değil, müşterinin yeni sürümü kendisinin kurduğu modelle ilerliyor; bu yüzden güncellemeler haftalar ya da aylar arayla yapılıyor
Asıl önemli olan bağımlılık izleme ve yayımlanmış açıkları kontrol etmek. Ürünün gerçekten etkilenip etkilenmediğini değerlendirdikten sonra, ancak o zaman ilgili bağımlılığı hemen güncellemek yeterli
Yeni sürüm çıkar çıkmaz mutlaka bugün güncellenmesi gerektiği yönünde bir algı var
Gerçek değişiklikleri incelemeden, “sonra daha zor olur, o yüzden şimdi yapalım” yaklaşımı verimsiz
Sürüm numaralarının en önünde kalmak güvenlik açısından ters etki bile yaratabilir
Bizim şirkette tarayıcı kritik bir açık bulursa 7 gün içinde güncelleme yapmak zorundayız
Süre aşılırsa uyum ihlali sayılıp karmaşık bir süreç başlıyor; bu yüzden çoğu ekip her şeyi hemen güncelliyor
Tarayıcı gibi yoğun dış girdi alan uygulamalar sık güncellenmeli; ama hava durumu uygulaması gibi girdisi sınırlı olanlar görece daha güvenli
Bunun yerine düzenli güncelleme yapıp tedarik zinciri saldırılarına karşı savunma önlemlerini birlikte uygulamak daha verimli olabilir
Debian stable modeli gibi, dağıtımın ortak bağımlılıkları yönettiği ve birkaç yılda bir toplu yükseltme yapılan yaklaşım giderek daha mantıklı görünüyor
Bazı ekosistemler fazla hızlı hareket ediyor ya da dağıtım bazlı paketleme yapıları yetersiz
Örneğin Node.js kütüphanelerini apt ile kurup projede kullanmak hâlâ zor
Temel bir değişim olmadan hızlı hareket eden ekosistemler sağlıklı değil
JS son 3 yılda neredeyse hiç gerçek ilerleme göstermedi, ama 3 yıllık bir projeyi yeniden build etmeye çalışınca yeniden yazım düzeyinde bir acı yaşanıyor
Arch gibi dağıtımlarda ise bazen hiç yok
Tedarik zinciri saldırılarını önlemek için bağımlılık güncellemelerine bir cooldown süresi koymanın, 0-day açıkları engellemek için en yeni sürümü hemen kullanmaktan daha iyi olduğu varsayılıyor
Mesele, güncellemenin yeni bir açık getirme olasılığı ile mevcut bir açığı kapatma olasılığını karşılaştırmak
SemVer'e göre patch sürümleri görece daha güvenli olduğundan, kısa bir cooldown süresi gibi bir yaklaşım da mümkün
Örneğin 2.3.4'ten sonra 2.4.0 çıktıysa, acil bir özellik ihtiyacı yoksa 2.4.1 çıkana kadar beklemek daha iyi olabilir
Çoğu güvenlik açığı kasıtlı saldırılardan değil, genel yazılım hatalarından kaynaklanır
Bağımlılıkların sayısını ve karmaşıklığını sınırlayan bir politika daha güçlü bir yaklaşım olabilir
“Her şeyi yapan kütüphaneler” yerine, yalnızca küçük ve amacı net bağımlılıklar eklenmeli
Ayrıca kütüphaneler de yalnızca güvenlik yamalarını içeren LTS sürümleri sunarsa yönetim kolaylaşır
Aynı şeyi yeniden yazmak israf olabilir. Sorunlu “everything library” için somut örneklerin ne olduğu merak ediliyor
Aynı geliştiriciye birden fazla kütüphane üzerinden güveniyorsanız, paket sayısından çok güven ilişkileri önemlidir
Karmaşıklık güvenlik açıklarıyla ilişkili olabilir ama doğrudan sebep değildir
Artık kısa vadeli hız yerine uzun vadeli bakım kolaylığını gözeten seçimler yapmak mümkün
C++ dünyasında bu bazen rekabet unsuru bile olabiliyor
Her seferinde en güncel sürüme geçme baskısı, yazılımın sürekli daha iyiye gittiği yönündeki yanlış inançtan kaynaklanıyor
Oysa bu, bilinen hataları yeni ve bilinmeyen hatalarla değiştirmek anlamına gelebilir
Açık issue'ları izleyip yalnızca gerektiğinde yama geçmek daha mantıklı olabilir
Yani eski sürümün daha güvenli olduğu bir örnek vardı
Belki de bunun nedeni zaten yeterince kararlı yazılımlar kullanıyor olmamız
Herkes “biraz bekleyelim” derse sonunda ortakların trajedisi gibi kimse ilk doğrulamayı yapan taraf olmayabilir
Bekledikçe teknik borç birikir; bu yüzden kademeli güncellemeler ve zero trust ile izleme gibi hafifletici önlemler gerekir
Bu sırada güvenlik tarayıcıları zaten açıkları tespit etmiş olur
Saldırgan yetkisiz bir release yayımladığında bunun fark edilmesi de mümkün olabilir
Cooldown fikri iyi olsa da, saldırganların bunu kötüye kullanıp sahte bir aciliyet yaratma riski var
“Acil güvenlik yaması” diyerek erken kurulum teşvik edilebilir ve o sürüm aslında zararlı olabilir
Bu tür psikolojik baskı saldırılarına karşı hazırlıklı olmak gerekir
Cooldown için bir başka gerekçe de, bakımcılara kendilerinin ihlal edildiğini fark etme zamanı tanımak
Saldırganlar bakımcıların yokluğunu hedef alır; örneğin tatil, konferans ya da resmi tatil dönemlerini
Birçok proje bir veya iki kişi tarafından yönetildiği için, bu zaman farkı çok önemli
Bu tamamen projenin niteliğine ve saldırı yüzeyine bağlı
Sadece “en iyi uygulamaları” takip etme dönemi artık bitmeli
Güvenlik, temaslı bir spor gibi her gün ayrıntılar üzerinde eleştirel düşünmeyi gerektiriyor
Sadece zaman geçince güvenli hâle geldiğini varsayan cooldown yaklaşımının sınırları da var
Kimse koda bakmıyorsa bir hafta sonra da risk aynen sürer
Bunun yerine kademeli dağıtım (gradual rollout) daha etkili olabilir
Her tüketici kendi gecikme süresini (delay factor) belirler; böylece riske daha açık olan taraflar önce sorunla karşılaşır,
bu sırada diğerleri korunur
Tehlikeli güncellemeler kuyruktan çıkarılır ve gecikmeli tüketiciler bunları hiç görmez
Son zamanlarda, tekerleği yeniden icat etmeye çalışmakla bağımlılık Tetris’ini yönetmeye çalışmak arasında hangisinin daha katlanılabilir olduğunu karıştırdığım zamanlar oluyor.
Bir şey bir süreliğine yanlışsa kendi kodumu düzeltmem yeterli oluyor ama bağımlılık Tetris’inde hangi tekerleğin bir anda yamulduğunu bulmak hem zor hem de debug etmesi daha da zor.