Ulaşım
- Adres: Kazımdirik Mah. 296.Sokak Ofis:1 No:314 Folkart Time | Bornova / İzmir
- Telefon:
0505 532 36 38 - eMail: admin@alestaweb.com
Sabah kalktınız, projenizde npm install çalıştırdınız ve hiçbir şey olmadı gibi göründü. Peki ya olduysa? 4 Ağustos 2026'da başlayan npm tedarik zinciri saldırısı (npm supply chain attack) tam olarak böyle işliyor: kurulum bitmeden, testleriniz çalışmadan önce sisteminizde kod yürütüyor. Alesta Web olarak bu rehberde ChainDrop — namıdiğer "Mini Shai-Hulud" — solucanının nasıl yayıldığını, hangi paketleri vurduğunu ve sunucunuzu, bilgisayarınızı nasıl temizleyeceğinizi adım adım anlatıyoruz.
Olay şöyle gelişti. Saldırganlar, çok kullanılan bir npm paket ailesinin bakımcısına ait hesabı ele geçirdi. Elde ettikleri yayınlama yetkisiyle paketlerin yeni sürümlerini kendileri yayınladılar. Ama bu sürümler normal bir güncelleme değildi: içlerine kimlik bilgisi çalan, üstelik kendi kendini çoğaltan bir zararlı yazılım yerleştirilmişti.
İşin can sıkıcı tarafı şu: bu npm tedarik zinciri saldırısı tek bir pakette kalmadı. Zararlı yazılım, çaldığı npm token'ıyla o kimliğin erişebildiği diğer paketleri de zehirledi. Yani bir solucan (worm) gibi yayıldı. Microsoft'un güvenlik ekibinin analizine göre kısa sürede 400'ün üzerinde paket sürümü bu şekilde yayınlandı.
Bu makaleyi okuyorsanız ve son bir hafta içinde Node.js projelerinizde bağımlılık kurduysanız, etkilenmiş olma ihtimaliniz gerçek. Aşağıdaki "Tespit" bölümünü atlamayın. Alesta Web ekibi olarak müşteri sunucularımızda ilk yaptığımız iş bu taramaydı.
Rakamlar konuyu daha net anlatıyor. Saldırıdan etkilenen ailedeki paketlerin bazıları haftada yüz milyonlarca kez indiriliyor. flat-cache ve file-entry-cache gibi kütüphaneler doğrudan sizin projenizde olmasa bile, kullandığınız bir test aracının ya da linter'ın bağımlılığı olarak sisteminize girmiş olabilir. Bu, klasik bir npm supply chain attack senaryosudur: siz hiçbir şey yapmasanız da, bağımlılığınızın bağımlılığı sizi vurur.
Adına Microsoft "ChainDrop" diyor, güvenlik topluluğu ise "Mini Shai-Hulud" olarak anıyor. İsim, daha önce benzer bir yöntemle yayılan bir zararlıdan geliyor. Teknik olarak tanımı şu: Bun tabanlı, ağır şekilde karartılmış (obfuscated), kendi kendini çoğaltan bir kimlik bilgisi hırsızı.
Şimdi bunu sadeleştirelim. Klasik bir zararlı yazılım bir dosyaya bulaşır ve orada durur. Bu solucan farklı çalışıyor:
1. Bakımcının npm token'ı ele geçirilir 2. Zararlı, o token ile erişilebilen TÜM paketleri listeler 3. Her paketin son tarball'ı indirilir 4. İçine zararlı + setup.mjs yükleyicisi eklenir 5. package.json'a "preinstall" hook'u eklenir 6. Patch sürümü artırılır (ör. 5.3.1 -> 5.3.2) 7. Paket yeniden yayınlanır -> yeni kurbanlar 8. Yeni kurbanın token'ı çalınır -> 1. adıma dön
Bu döngü, saldırının neden bu kadar hızlı büyüdüğünü açıklıyor. Her yeni kurban, yeni bir yayılma noktası oluyor. Klasik bir npm tedarik zinciri saldırısı tek bir bakımcıyla sınırlı kalırken, bu solucan bakımcıdan bakımcıya atlıyor.
Zararlı sürümlerin çoğunda GitHub tarafında karşılık gelen bir commit, pull request ya da tag yok. Yani kaynak koda bakıp "temiz görünüyor" demek yetmiyor. Kod deposu temiz olabilir ama npm'e yüklenen tarball zehirli olabilir. Bu ayrım çok önemli, çünkü çoğu ekip sadece kaynak koda bakıyor.
Saldırının merkez üssü, önbellekleme (caching) araçları üreten bir paket ailesiydi. Aşağıdaki tablo, en çok konuşulan paketleri ve yaklaşık indirme hacimlerini gösteriyor. Rakamlar kamuya açık güvenlik raporlarından derlenmiştir.
| Paket / Package | İşlevi / Purpose | Yaklaşık İndirme |
|---|---|---|
keyv |
Anahtar-değer depolama (key-value storage) | ~127 milyon / hafta |
flat-cache |
Dosya tabanlı önbellek (file cache) | ~565 milyon / ay |
file-entry-cache |
ESLint önbellek altyapısı | ~557 milyon / ay |
cacheable |
Önbellek katmanı (caching layer) | ~29 milyon / ay |
cache-manager |
Çok katmanlı önbellek yöneticisi | Yüksek |
Listeye bakıp "ben bunları kullanmıyorum" demeyin. file-entry-cache paketini doğrudan kuran neredeyse yok; ama ESLint kullanan herkesin node_modules klasöründe duruyor. Alesta Web olarak incelediğimiz projelerin büyük kısmında bu paketler dolaylı bağımlılık (transitive dependency) olarak yer alıyordu.
Toplamda 1.300'ü aşkın paket sürümünün etkilendiği, bu sürümlerin birleşik aylık indirme hacminin milyarlarla ifade edildiği raporlandı. Bu ölçek, olayı 2026'nın en geniş çaplı npm tedarik zinciri saldırısı yapıyor.
Şimdi işin teknik kısmına gelelim. Bunu anlamanız önemli, çünkü korunma yöntemi doğrudan buradan çıkıyor.
npm, bir paketi kurarken belirli aşamalarda paketin kendi tanımladığı komutları çalıştırır. Bunlara lifecycle script denir. preinstall, adından da anlaşılacağı gibi kurulum tamamlanmadan önce çalışır.
{
"name": "ornek-paket",
"version": "5.3.2",
"scripts": {
"preinstall": "node setup.mjs"
}
}
Kritik nokta şurada: bu komut, siz henüz kodu incelemeden, testler çalışmadan, güvenlik taramanız devreye girmeden yürütülür. Yani geliştirici bilgisayarında ve CI/CD sunucusunda kod çalıştırma imkânı, npm install yazdığınız anda saldırganın eline geçer.
setup.mjs dosyası tek başına zararsız görünür. Yaptığı iş, bağımsız bir Bun çalışma zamanı (runtime) indirmek ve asıl karartılmış paketi onunla çalıştırmaktır. Neden Bun? Çünkü sistemde kurulu Node.js'in güvenlik eklentileri, izleme araçları ya da sürüm kısıtları devreden çıkmış olur. Saldırgan kendi getirdiği yorumlayıcıyı kullanır.
Sisteminizde node_modules altında bun-dl- ile başlayan klasörler ya da Math_Symbol.js, Math_init.js gibi tuhaf isimli dosyalar görüyorsanız bu ciddi bir uyarı işaretidir. Hemen "Temizlik" bölümüne geçin.
Toplanan veriler JSON'a çevrilir, gzip ile sıkıştırılır, rastgele bir anahtarla AES-256-GCM kullanılarak şifrelenir; anahtar da saldırganın RSA açık anahtarıyla korunur. Ana kanal saldırganın kontrolündeki bir HTTPS adresidir. O kanal kapanırsa zararlı, kurbanın GitHub hesabında herkese açık bir depo oluşturup şifreli veriyi oraya commit eder.
Bu, savunma açısından ilginç bir detay: engellediğiniz tek bir alan adı saldırıyı durdurmuyor. Bu yüzden npm supply chain attack vakalarında ağ seviyesinde engelleme tek başına yeterli bir çözüm değildir.
Zararlı yalnızca dosyalarda token deseni aramıyor. Bulduğu kimlik bilgileriyle gerçekten API çağrısı yapıp erişimi doğruluyor ve o kimliğin ulaşabildiği başka sırları da topluyor. Hedef listesi:
Son madde özellikle sinsi. CI/CD ortamınızda çalışan bir npm install, o iş akışına verilmiş bulut yetkilerini de ele verebilir. Yani bir geliştiricinin dizüstü bilgisayarıyla sınırlı kalmayan, doğrudan üretim altyapınıza uzanan bir risk söz konusu.
Ek olarak zararlı, çaldığı GitHub yetkisiyle depolara kalıcılık bırakmaya çalışıyor: editör ve yapay zekâ asistanı yapılandırma yollarına kendi dosyalarını enjekte ediyor. Alesta Web olarak müşteri projelerinde bu tip yapılandırma dosyalarını da ayrıca denetlemenizi öneriyoruz.
Panik yapmadan, sırayla ilerleyelim. Aşağıdaki komutlar hem yerel makinenizde hem sunucunuzda çalışır.
# Zararlı yükleyici izleri find . -path ./.git -prune -o -name "setup.mjs" -print find . -name "Math_Symbol.js" -o -name "Math_init.js" # Indirilmis Bun calisma zamani izi find . -type d -name "bun-dl-*"
Get-ChildItem -Recurse -Filter setup.mjs -ErrorAction SilentlyContinue Get-ChildItem -Recurse -Include Math_Symbol.js,Math_init.js -ErrorAction SilentlyContinue
grep -rl '"preinstall"' node_modules/*/package.json 2>/dev/null
# Daha okunakli cikti
for f in node_modules/*/package.json; do
node -e "const p=require('./$f'); if(p.scripts&&p.scripts.preinstall) console.log(p.name, '->', p.scripts.preinstall)" 2>/dev/null
done
Meşru paketlerin de preinstall kullandığını unutmayın (özellikle native modüller). Amaç her sonucu silmek değil, node setup.mjs gibi tanımadığınız komutları yakalamak.
npm ls keyv cacheable flat-cache file-entry-cache cache-manager # Kilit dosyasinda hangi surumler var? grep -A2 -E '"(keyv|cacheable|flat-cache|file-entry-cache)"' package-lock.json | head -40
Kurumsal ortamdaysanız, uç nokta tespit çözümünüzde şu davranışları arayın: node sürecinin setup.mjs çalıştırması, ardından node tarafından bir bun ikilisinin başlatılması, ve bun sürecinin gh auth token ya da az account get-access-token gibi komutları çağırması. Bu zincir, normal bir geliştirme akışında görülmez.
Yukarıdaki dört adım da temiz çıktıysa büyük ihtimalle etkilenmediniz. Yine de "Korunma" bölümündeki min-release-age ayarını uygulayın — bir dahaki sefere hazırlıklı olursunuz.
Şüpheli bir iz bulduysanız sıra kritik kısımda. Buradaki sıralama önemli: önce kimlik bilgilerini iptal edin, sonra temizleyin. Tersini yaparsanız, temizlik sürerken çalınmış token hâlâ geçerli olur.
Token iptal işlemini etkilenen makineden yapmayın. Zararlı hâlâ aktifse yeni ürettiğiniz token'ı da çalar. Temiz bir bilgisayar ya da telefon üzerinden web arayüzünü kullanın.
# Kirli klasoru ve onbellegi kaldir rm -rf node_modules npm cache clean --force # Kilit dosyasindaki surumlerle, script calistirmadan kur npm ci --ignore-scripts # Sonra sadece guvendigin paketlerin build adimini elle calistir npm rebuild --foreground-scripts
--ignore-scripts bayrağı burada hayat kurtarıcı. Kurulum sırasında hiçbir lifecycle script'i çalışmaz; böylece zehirli bir sürüm sisteminize hâlâ inse bile kod yürütemez.
# Ornek: saldiri oncesi bir surume sabitle npm install keyv@5.3.1 --save-exact # package.json'da caret kaldirildi mi kontrol et grep -E '"(keyv|cacheable)"' package.json
Bu adım sık atlanıyor. Geliştirici makinesini temizlersiniz ama CI sunucusundaki node_modules önbelleği zehirli kalır ve bir sonraki derlemede sorun geri döner. Yapı önbelleğini (build cache) tamamen geçersiz kılın, artifact deposundaki kirli sürümleri karantinaya alın.
# Iz kalmadigini dogrula find . -type d -name "bun-dl-*" | wc -l # 0 olmali grep -rl "setup.mjs" node_modules 2>/dev/null | wc -l # 0 olmali # Bagimlilik agacinda bilinen kotu surum var mi? npm audit
Tek seferlik temizlik iyi, ama asıl mesele bir dahakine hazırlıklı olmak. Bu tür bir npm tedarik zinciri saldırısı yılda birkaç kez tekrarlanıyor ve her seferinde daha rafine hale geliyor.
npm 12 ile gelen bu özellik basit ama çok etkili bir fikre dayanıyor: yeni yayınlanmış bir sürümü hemen kurma, birkaç gün beklet. Kötü niyetli sürümler genellikle saatler içinde fark edilip kaldırılıyor. Siz 3 gün beklerseniz, o pencereyi tamamen atlarsınız.
# npm'i guncelle npm install -g npm@12 npm --version # Yeni surumleri 3 gun beklet npm config set min-release-age 3d # Proje bazinda: .npmrc dosyasina ekle echo "min-release-age=3d" >> .npmrc
# .npmrc (repo koku) ignore-scripts=true audit=true # CI adimi npm ci --ignore-scripts
package-lock.json dosyasını sürüm kontrolüne mutlaka ekleyin ve CI'da npm install yerine npm ci kullanın. npm ci yalnızca kilit dosyasındaki tam sürümleri kurar; sizin haberiniz olmadan yeni bir sürüm çekmez.
Müşteri projelerimizde uyguladığımız pratik kural şu: üretim derlemesi (production build) internete paket indirmek için çıkmaz. Bağımlılıklar önceden doğrulanmış bir iç ayna (mirror) üzerinden gelir. Böylece npm tarafında ne olursa olsun, üretim hattınız etkilenmez.
Evet. preinstall hook'u kurulum tamamlanmadan çalıştığı için, indirme ve çıkarma aşamasını geçen her komut riskli. npm install yazdıysanız kurulum "başarısız" bitse bile kod çalışmış olabilir.
Evet. Sorun paket yöneticisinde değil, npm kayıt defterindeki (registry) zehirli paketlerde. Yarn ve pnpm de aynı paketleri aynı kayıt defterinden çeker. İyi haber: pnpm ve yarn tarafında da script çalıştırmayı kısıtlayan ayarlar var.
Tam olarak değil. npm audit bilinen ve kaydedilmiş güvenlik açıklarını gösterir. Yeni yayınlanmış zehirli bir sürüm veri tabanına işlenene kadar orada görünmez. Bu yüzden dosya seviyesindeki taramayı da yapın.
Zararlı doğrudan veri tabanı içeriği kopyalamıyor; kimlik bilgisi topluyor. Ancak çalınan bir bulut anahtarı ya da SSH anahtarı, saldırgana veriye erişim yolu açabilir. Bu yüzden anahtar döndürme (key rotation) adımı ertelenmemeli.
Bu makaledeki teknik bilgiler aşağıdaki kamuya açık güvenlik analizlerinden derlenmiş ve Alesta Web ekibi tarafından doğrulanmıştır:
Bu npm tedarik zinciri saldırısı bize şunu hatırlattı: bağımlılık listeniz aslında güven listenizdir. Alesta Web olarak geliştirdiğimiz tüm projelerde kilit dosyası disiplini ve script kısıtlaması standarttır — bu olaydan sonra bunu daha da sıkılaştırdık.
Hızlı Özet / Quick Summary:
setup.mjs ve bun-dl-* izlerini tarayın (scan for indicators)rm -rf node_modules + npm ci --ignore-scripts ile temiz kurulummin-release-age=3d ile bir dahakine hazırlanınnpm ci kullanınFaydalı Bağlantılar / Useful Links:
Sunucunuzda ya da projenizde bu saldırıya dair bir iz bulduysanız ve nasıl ilerleyeceğinizden emin değilseniz, Alesta Web ekibiyle alestaweb.com üzerinden iletişime geçebilirsiniz. Tecrübemize göre en kritik saat, ilk 24 saattir.
© 2026 Alesta Web — Tüm hakları saklıdır.