- NPM deposunda kimlik bilgisi hırsızlığı için hazırlanmış 100’den fazla kötü amaçlı paketin ağustostan bu yana tespit edilmeden yüklendiği ve toplamda 86 binden fazla kez indirildiği doğrulandı
- Güvenlik şirketi Koi, 'PhantomRaven' adını verdiği saldırı kampanyasının NPM’in Remote Dynamic Dependencies (RDD) özelliğini kötüye kullanarak 126 kötü amaçlı paket dağıttığını bildirdi
- RDD, paketlerin güvenilmeyen alan adlarından bağımlılık kodunu dinamik olarak indirmesine olanak tanıyan bir yapı ve bu nedenle statik analiz araçları tarafından tespit edilmiyor
- Saldırganlar bu özelliği kullanarak HTTP bağlantısı üzerinden kötü amaçlı kod indirdi; paket meta verilerinde ise “0 Dependencies” olarak göründüğü için geliştiriciler ve güvenlik tarayıcıları bunu fark etmedi
- Bu yapısal zafiyet, NPM ekosistemindeki güvenlik yönetiminin sınırlarını ve otomatik kurulum mekanizmasının risklerini ortaya koyuyor
NPM deposunda kötü amaçlı paketlerin yayılması
- Saldırganlar, NPM kod deposundaki yapısal zayıflıkları kullanarak ağustostan bu yana 100’den fazla kimlik bilgisi hırsızlığı amaçlı paket yükledi
- Paketlerin çoğu tespit edilmeden dağıtıldı ve toplam indirilme sayısı 86.000’in üzerine çıktı
- Güvenlik şirketi Koi, bu saldırıyı PhantomRaven kampanyası olarak adlandırdı ve NPM’in belirli bir özelliğinin kötüye kullanıldığını analiz etti
- Koi’ye göre 126 kötü amaçlı paketin yaklaşık 80’i, haberin yazıldığı sırada hâlâ NPM’de bulunuyordu
Remote Dynamic Dependencies (RDD) yapısındaki zafiyet
- RDD, paketlerin harici web sitelerinden bağımlılık kodunu dinamik olarak indirmesine izin veren bir özellik
- Normalde bağımlılıklar NPM’in güvenilir altyapısından indirilir; ancak RDD, HTTP gibi şifrelenmemiş bağlantılar üzerinden indirmeye de izin veriyor
- PhantomRaven saldırganları bu özelliği kullanarak kodun kötü amaçlı URL’lerden indirilmesini sağladı (ör.
http://packages.storeartifact.com/npm/unused-imports)- Bu tür bağımlılıklar geliştiriciler ve güvenlik tarayıcıları tarafından görünmez kalıyor ve paket bilgilerinde “0 Dependencies” olarak listeleniyor
- NPM’in otomatik kurulum özelliği nedeniyle bu tür 'görünmez' bağımlılık kodları otomatik olarak çalıştırılıyor
Güvenlik araçlarının tespit sınırları
- Koi’den Oren Yomtov, “PhantomRaven, mevcut güvenlik araçlarının kör noktalarını ustalıkla kötüye kullanan bir örnek” dedi
- RDD, statik analiz araçları tarafından tespit edilmiyor
- Bu sayede saldırganlar güvenlik doğrulamalarını atlatıp kötü amaçlı kod dağıtabildi
Ek zafiyet unsurları
- Koi, RDD ile indirilen bağımlılıkların her kurulumda saldırganın sunucusundan yeniden indirildiğini açıkladı
- Önbellek veya sürüm yönetimi olmadığı için, aynı paket kurulsa bile her seferinde farklı kötü amaçlı kodun enjekte edilmesi mümkün
- Bu dinamik indirme yapısı, paket bütünlüğünün doğrulanmasını zorlaştırıyor
NPM’in yapısı ve arka plan
- NPM, JavaScript için bir paket yöneticisi olup GitHub iştiraki npm, Inc. tarafından yönetiliyor
- Node.js’in varsayılan paket yöneticisidir ve bir komut satırı istemcisi ile npm registry'den oluşur
- registry, herkese açık ve ücretli özel paketleri barındırır; ayrıca web sitesi üzerinden aranabilir
- Bu olay, NPM’in otomatik bağımlılık yönetimi yapısının saldırılar için kötüye kullanılabildiğini gösteren bir örnek olarak değerlendiriliyor
Diğer notlar
- Haberin sonunda gereksiz JavaScript çalıştırmanın engellenmesi gerektiği yönünde bir görüşe yer verildi
- Ancak bu saldırı, zorunlu JavaScript kodunun bile kötüye kullanılabildiğini gösteren bir örnek olarak işaret ediliyor
2 yorum
Gerçek zamanlı bir tarayıcı betiği hazırladım.
Şüpheli deponun path'inde
npx sha1-hulud-scannerkomutunu girmeniz yeterli.
Kaynak kodu: https://github.com/developerjhp/sha1-hulud-scanner
Hacker News yorumu
Bu aralar
npmkomutunu Docker container’ı içinde çalışacak şekilde alias’ladımBöylece ortam değişkenlerimi açığa çıkarmıyor, mevcut dizin dışındaki dosyalara erişemiyor ve
.bashrcgibi yapılandırma dosyalarına da ulaşamıyorNot: Run tools inside Docker
npm, hemen çalıştırılacak rastgele kodu indiriyorOnun yerine
pnpmöneririm. Varsayılan olarak lifecycle script’lerini çalıştırmıyor ve izin verilecek script’leri whitelist ile belirleyebiliyorsunGerçek koruma istiyorsan yalnızca kurulum değil, tüm çalıştırma sürecini sandbox içinde yürütmelisin
Şu an sadece post-install’ı engellemek yarım bir önlemden ibaret. Tedarik zinciri saldırıları giderek daha tehlikeli hale geliyor
neovimya davscodeenfekte olursa, kullanıcı yetkileriyle zaten yeterince tehlikeli işler yapılabilirBasit alias yaklaşımı
node/npmiçin işe yarıyor ama diğer programlara uygulaması zor. Çünkü container’a gerekli kaynakları mount etmen gerekiyorBunu uzun zamandır merak ediyordum. İnsanlar neden
npm’i sistem üzerinde bu kadar rahat çalıştırıyor?makegibi tekrarlanabilir build süreçlerine alışmış biri olarak,npm’in her seferinde farklı şeyler indirip farklı sonuçlar üretmesi bana şok edici gelmiştiCSS üretiminin bile npm bağımlılıklarına bağlanması tuhaftı. Bu yüzden npm ortamını komple Docker içinde dondurmayı (freeze) denedim ama sonunda kaybedilmiş bir savaş gibi geldi
maven,nuget,pip,npmhepsi aynıEskisi gibi dağıtım paket yöneticilerine bağlı kalsaydık bugünkü hızlı ekosistem mümkün olmazdı
Yine de güvenliği artırılmış yeni paket yöneticileri ortaya çıkıyor. Sebebini anlamadan sadece yöntemi suçlamak doğru değil
npm’i Docker ile sabitlediysen, bağımlılıkları her güncelledikten sonra o ortamı doğrulayıp doğrulamadığını merak ediyorumAslında
npmvepnpmzaten varsayılan olarak bağımlılıkları lock dosyalarıyla sabitliyornpm install thing”in fazla kolay ve ucuz olmasıBirçok açık kaynak proje kaliteden çok CV’yi dolduran kodlarla doluyor ve sonunda büyük şirketlerin reklam takipçileri ya da cüzdan uygulamaları gibi şeyleri yapmak için kullanılıyor
npm installsadece paket indirmiyor, aynı zamanda kod çalıştırıyorpackage.jsoniçindeki preinstall, install, postinstall hook’ları gerçekten çalıştırılıyorKurulum sırasında keyfi komutlar çalıştırmak için meşru bir gerekçe ne olabilir ki?
İlgili rapor: PhantomRaven npm malware
Başka bir örnek: Socket.dev blogu
Örneğin Linux kernel paketleri kurulumdan sonra initramfs yeniden oluşturma, GRUB güncelleme gibi işler için post-install script’leri çalıştırır
DEB/RPM paketlerinin çoğunda bu tür script’ler bulunur. Yani sorun tasarımın kendisinde
npm’e herkes paket yükleyebiliyorLinux dağıtımlarında güvenilir bir maintainer sistemi var ve hatta bazen PGP tabanlı bir root of trust doğrudan kuruluyor
Buna karşılık
npm,pip,rubygems,cargogibi yapılar aslında sadece “curl | bash”in daha şık bir versiyonuBakım yükünü azaltmak için bu tür post-install build’lerine ihtiyaç duyulmuş
Package.swiftdosyasını gerçekten çalıştırıyorAma duyduğuma göre oldukça sıkı sandboxing uygulanıyor, bu yüzden kötüye kullanmak zor
Not: SwiftPM belgeleri, PackageDescription
pnpm v10, varsayılan olarak tüm lifecycle script’lerini devre dışı bırakıyor ve kullanıcının bunlara açıkça izin vermesini istiyorİlgili tartışma
Son dönemdeki
npmsaldırılarına bakınca, artıknpmile geliştirme yapmak güvenli mi diye düşünmeden edemiyorumHer React projesine başlarken yüzlerce paket kuruluyor ve ne yaptıklarını bilmiyorum
Backend’de yalnızca gereken paketleri açıkça kuruyorsun ama frontend tam bir güvenlik açığı Pandora’nın kutusu gibi
npmen büyük olanı ve haberlerde en çok o çıkıyorjj’yi kurduğumda 470, Python’dakiwan2gpiçinse 211 paket kuruldu. Hepsi aşağı yukarı aynıxzvakasında olduğu gibi, her bağımlılık rastgele bireylere bağlı ve onların sosyal mühendislik saldırılarına kanmayacağını ummak zorundasınPyPIda güvenli değil. GitHub Actions’ın ele geçirilmesiyle meşru paketlere zararlı kod eklendiği vakalar da olduAngular, Vue gibi framework’lerle geliştirme yaptığım her seferinde tedirgin oluyorum
node_modulesiçindeki binlerce bağımlılığı görünce bu bana yaklaşan bir felaketin habercisi gibi geliyorAçık kaynak geliştiricilerden biri phishing’e düşse anında bulaşabilir
JavaScript ekosistemi temelden bozuk. Tek bir yazım hatasıyla tedarik zinciri saldırısına açık hale geliyorsun
NuGet ya da Maven’de de mümkün ama oralarda standart kütüphane daha büyük, bağımlılık daha az ve bir ölçüde kontrol hissi var
Mükemmel değil ama yine de bir adım daha iyi
86.000 indirme içinde büyük kısmın gerçek kullanıcıdan ziyade otomatik tarayıcılar ya da botlar olma ihtimali yüksek
Yeni bir sürüm yüklediğinde bir iki gün içinde yüzlerce kez indiriliyor ama bunlar gerçek insanlar olmayabilir
Yani enfekte olmuş kullanıcı sayısı neredeyse hiç olmayabilir
AI chatbot’ların halüsinasyonla uydurduğu paket adlarını hedef alan saldırılar da çok yaygın. Yani mesele yalnızca basit istatistikler değil
Saldırının daha ayrıntılı açıklaması için BleepingComputer haberine bakılabilir
npm installsırasında bağımlılık olarak HTTP URL kullanan paketleri tespit etmenin ya da filtrelemenin bir yolu var mı diye merak ediyorumİstek sahibine göre farklı payload gönderilebildiği için, bunu genel amaçlı tarayıcılarla yakalamak zor olabilir
Hobi geliştiricisi olarak bu tür tedarik zinciri saldırılarına karşı nasıl hazırlanmak gerektiğini düşünüyorum
Popüler tutorial’ları izleyip bağımlılık kurdukça insan fark etmeden güvenlik konusunda gevşiyor
Homelab’imde de çeşitli servisler çalıştırıyorum; ya bir bot sızarsa diye endişeleniyorum. Nereden başlamak gerekir?
Mükemmel garanti vermez ama tüm sunucunun ele geçirilmesinden çok daha iyidir
Gereken kodu doğrudan kopyalayıp kullanmak da hem iyi bir öğrenme yöntemi hem de daha güvenli bir yaklaşım olabilir
Böyle bir yapıda, milyonlarca kullanıcının tek tek doğrulama yapmasına gerek kalmadan dağıtım düzeyinde güven sağlanabilir
Örnek: Hono, Zod
Ben yakın zamanda Bun’a geçtim; varsayılan olarak DB driver’ı veya S3 client’ı gibi şeyler yerleşik geldiği için ek indirme ihtiyacı azalıyor
Lifecycle hook’larda bağımlılık çekme yapısı her zaman bir saldırı dönüm noktası olabilir
Şu an meşru görünse bile, ileride sahibi hacklenirse ya da fikrini değiştirirse zararlı koda dönüşebilir
Bu tür kurulum hook’ları sonuçta sürdürülebilir olmayan bir tasarım