4 puan yazan GN⁺ 2025-12-15 | 3 yorum | WhatsApp'ta paylaş
  • Kötü amaçlı Shai-Hulud 2.0 npm paketi geliştirici makinelerini enfekte ederek Trigger.dev’in GitHub organizasyonu erişimini ele geçiren bir olaya yol açtı
  • Enfeksiyon, geliştiricinin pnpm install çalıştırmasıyla kötü amaçlı paketin preinstall script’inin devreye girmesiyle başladı; TruffleHog aracı kullanılarak kimlik bilgileri çalındı
  • Saldırganlar 17 saat boyunca 669 depoyu klonladı, ardından 10 dakika içinde 199 branch’e force push yapmayı ve 42 PR’ı kapatmayı denedi
  • Paketler ve production sistemleri zarar görmedi; saldırı 4 dakika içinde tespit edilip hesap erişimi engellendi
  • Olayın ardından npm script’lerinin devre dışı bırakılması, pnpm 10 yükseltmesi, OIDC tabanlı npm dağıtımı, branch protection’ın tüm depolarda uygulanması gibi güvenlik önlemleri güçlendirildi

Saldırıya genel bakış

  • 25 Kasım 2025’te, dahili Slack üzerinden yapılan hata ayıklama sırasında birden fazla depoda Linus Torvalds adına atılmış “init” commit’i görülmesiyle anormal bir durum fark edildi
  • İnceleme sonucunda, Shai-Hulud 2.0 tedarik zinciri solucanının geliştirici makinesini enfekte ederek GitHub kimlik bilgilerini çaldığı doğrulandı
  • Bu solucanın 500’den fazla npm paketini enfekte ettiği ve 25.000’den fazla depoyu etkilediği bildirildi
  • Trigger.dev’in resmi npm paketleri (@trigger.dev/*, CLI) enfekte olmadı

Saldırı zaman çizelgesi

  • 24 Kasım 04:11 UTC: Kötü amaçlı paketlerin dağıtımı başladı
  • 20:27 UTC: Almanya’daki bir geliştirici makinesi enfekte oldu
  • 22:36 UTC: Saldırgan ilk erişimi elde etti ve büyük ölçekli depo klonlamaya başladı
  • 15:27~15:37 UTC (25 Kasım): 10 dakika süren yıkıcı saldırı gerçekleştirildi
  • 15:32 UTC: Anormallik tespit edildi ve 4 dakika içinde erişim engellendi
  • 22:35 UTC: Tüm branch’lerin geri yüklenmesi tamamlandı

Enfeksiyon süreci

  • Geliştirici pnpm install çalıştırdığında, kötü amaçlı paketin preinstall script’i çalışarak TruffleHog’u indirip yürüttü
  • TruffleHog, GitHub token’ları, AWS kimlik bilgileri, npm token’ları, environment variable’lar gibi verileri tarayıp dışarı sızdırdı
  • Enfekte makinede .trufflehog-cache dizini ve ilgili dosyalar bulundu
  • Enfeksiyona neden olan paket silindiği için iz sürülemedi

Saldırganın faaliyetleri

  • Enfeksiyonun ardından 17 saat boyunca keşif faaliyetleri sürdürüldü
    • ABD ve Hindistan merkezli altyapı kullanılarak 669 depo klonlandı
    • Geliştirici faaliyetleri izlenerek GitHub token’ı üzerinden erişim sürdürüldü
    • “Sha1-Hulud: The Second Coming” adlı bir depo oluşturuldu; bunun kimlik bilgilerini saklamak için kullanıldığı tahmin ediliyor
  • Ardından 10 dakika boyunca yıkıcı eylemler gerçekleştirildi
    • 16 depoda 199 branch’e force push yapılmaya çalışıldı
    • 42 PR kapatıldı; bazıları branch protection ayarları sayesinde engellendi
    • Tüm commit’ler “Linus Torvalds <email> / init” biçiminde göründü

Tespit ve müdahale

  • Anormallikler Slack uyarıları üzerinden gerçek zamanlı olarak tespit edildi
  • 4 dakika içinde enfekte hesabın GitHub erişimi kesildi; ardından AWS, Vercel, Cloudflare dahil tüm servis erişimleri geri çekildi
  • AWS CloudTrail log analizi, yalnızca read-only API çağrıları bulunduğunu ve production verilerine erişim olmadığını gösterdi
  • AWS ayrıca Shai-Hulud ile ilişkili şüpheli etkinlikleri bağımsız olarak tespit edip uyarı gönderdi

Etki ve kurtarma

  • 669 depo klonlandı, 199 branch’e force push denendi, 42 PR kapatıldı
  • GitHub’da sunucu tarafı reflog bulunmaması kurtarmayı zorlaştırdı; ancak Event API ve yerel reflog kullanılarak tüm ortam 7 saat içinde geri yüklendi
  • npm paketleri ve production altyapısı zarar görmedi

GitHub App anahtarının açığa çıkması

  • İnceleme sırasında geliştiricinin dizüstü bilgisayarının çöp kutusunda bir GitHub App private key bulundu
  • Bu anahtar müşteri depolarında read/write yetkisine sahipti ve hemen rotate edildi
  • Veritabanı (installation ID’lerin tutulduğu yer) zarar görmediği için müşteri depolarına erişim olduğuna dair kanıt bulunmadı, ancak bu olasılık tamamen dışlanamıyor
  • GitHub destek ekibinden ek log istendi ve müşterilere e-posta bildirimi gönderildi

Shai-Hulud teknik analizi

  • setup_bun.js çalıştırıldığında Bun runtime kuruluyor ve arka planda bun_environment.js yürütülüyor
  • TruffleHog kullanılarak $HOME dizinindeki kimlik bilgileri toplanıyor
  • Toplanan veriler (contents.json, cloud.json, truffleSecrets.json vb.) rastgele GitHub depolarına üç kat base64 encoded biçimde yükleniyor
  • npm token’ı varsa, enfekte hesabın paketleri değiştirilip yeniden yayımlanarak solucan yayılıyor
  • Kimlik bilgileri yoksa home dizinini silmeye çalışma davranışı gösteriyor
  • Enfeksiyon göstergesi dosyalar: setup_bun.js, bun_environment.js, .trufflehog-cache/ vb.

Güvenlik güçlendirme önlemleri

  • npm script’leri tamamen devre dışı bırakıldı (ignore-scripts=true)
  • pnpm 10’a yükseltildi: script’ler varsayılan olarak devre dışı, minimumReleaseAge (3 gün) ayarıyla yeni paket kurulumları geciktiriliyor
  • Uzun ömürlü token’ları kaldırmak için OIDC tabanlı npm Trusted Publishers benimsendi
  • Tüm depolarda branch protection uygulandı
  • AWS SSO için Granted devreye alındı, session token’ları şifrelendi
  • GitHub Actions içinde harici katkıcıların workflow çalıştırmaları için onay zorunlu hale getirildi

Diğer ekipler için çıkarımlar

  • npm kurulumu sırasında çalışan keyfi kod yürütme yapısı başlı başına bir saldırı yüzeyi
  • ignore-scripts=true ayarı kullanılmalı ve yalnızca gerekli paketler whitelist ile yönetilmeli
  • pnpm minimumReleaseAge ile yeni paket kurulumları geciktirilmeli
  • Branch protection ve OIDC tabanlı dağıtım zorunlu güvenlik önlemleri olarak görülmeli
  • Yerel makinede uzun ömürlü kimlik bilgileri saklanmamalı; dağıtım yalnızca CI üzerinden yapılmalı
  • Slack uyarılarındaki gürültü, tespitin anahtarı oldu

İnsani boyut

  • Enfekte olan geliştiricinin bir hatası yoktu; olay yalnızca npm install çalıştırılmasıyla meydana geldi
  • Saldırı sırasında ilgili hesabın yüzlerce rastgele depoyu otomatik olarak ‘star’ladığına dair izler bulundu
  • Olay, bireysel bir hatadan ziyade ekosistemin yapısal zayıflığını ortaya koydu

Özet metrikler

  • İlk enfeksiyondan ilk saldırıya kadar: yaklaşık 2 saat
  • Saldırganın erişimi sürdürdüğü süre: 17 saat
  • Yıkıcı eylemlerin süresi: 10 dakika
  • Tespite kadar 5 dakika, engellemeye kadar 4 dakika
  • Tam kurtarma için geçen süre: 7 saat
  • Klonlanan depo: 669 / Etkilenen branch: 199 / Kapatılan PR: 42

Referans kaynaklar

  • Socket.dev: Shai-Hulud Strikes Again V2
  • PostHog, Wiz, Endor Labs ve HelixGuard analiz raporları
  • npm Trusted Publishers, pnpm onlyBuiltDependencies, minimumReleaseAge, Granted belgeleri

3 yorum

 
click 2025-12-15

pnpm varsayılan olarak post-install işlemlerini tek tek izin verecek şekilde tasarlanmıştı ama sonuçta geliştiriciler de bunu farkında olmadan izin veriyor gibi görünüyor

 
lamanus 2025-12-16

Anladığım kadarıyla, npm varsayılan olarak çalıştığı için pnpme geçip bunu varsayılan olarak devre dışı bırakarak güvenliği güçlendirmişler.

 
GN⁺ 2025-12-15
Hacker News yorumları
  • npm install çalıştırmak ihmalkârlık değildir
    Sorun, paket kurulum sürecinde keyfi kod çalıştırılmasına izin veren ekosistemdir
    Ama asıl güvenlik başarısızlığı, üçüncü tarafların hiçbir doğrulama olmadan ürününüze kod itebilmesini sağlayan bir paket yöneticisi kullanmaktır
    Sonuçta paket yöneticilerine ve onları işletenlerin iyi niyetine ve yetkinliğine sonsuz biçimde bağımlıyız
    Ayrıca OP'nin kimlik bilgilerini dosya sisteminde düz metin olarak sakladığını ima ediyor gibi görünüyor

    • Bence ikisi de sorun
      Dil düzeyinde, kodun girdileri okumasını, kaynak tüketmesini ve yalnızca tip açısından doğru çıktı üretmesini sınırlayan bir yapı kurulabilir
      Bu, tedarik zinciri sorununu tamamen çözmez ama maruz kalma alanını ciddi biçimde azaltır
    • Bu mantık fazla döngüsel
      “Bir kişinin böyle araçları kullanması yanlış değil ama herkes kullanınca ekosistem sorunlu” demek gibi
      Birçok geliştirme aracının güvenlik açısından zayıf olduğu zaten defalarca kanıtlandı
      Gerçekten önemsiyorsanız, bunu davranışlarınızla göstermelisiniz
    • IDE eklentileri de aynı
      VS Code kullanırken, küçücük bir özellik eklemek için bile kimin yaptığı belli olmayan bir eklenti kurmak zorunda kalmam can sıkıcıydı
    • Üçüncü taraf kod çalıştırmayı engelleyen bir paket yöneticisinin nasıl tasarlanabileceğini merak ediyorum
      Sonuçta yine de güvenmek zorunda olduğunuz kodu çalıştıran bir yapı olmuyor mu?
    • Bazı araçlar HTTP kimlik doğrulaması için yalnızca netrc dosyasını destekliyor
      giti HTTP üzerinden kullanırsanız, böyle bir düz metin kimlik bilgisi sızıntı yolu neredeyse her zaman vardır
  • pnpm bakımcısı 1 yıl önce “post-install script'lerini varsayılan olarak engelleyelim” diye önermişti
    Kullanıcı açısından rahatsız edici olabilirdi ama uzun vadede herkesin memnun kalacağı bir değişiklik olduğuna inanıyordu
    İlgili PR: pnpm/pnpm#8897

    • Buna rağmen aynı sorun hâlâ tekrarlanıyor
      Sonuçta bu da kolaylığın güvenliği yenmesine dair bir örnek daha
  • “Veritabanı ihlal edilmedi” denmiş ama saldırgan AWS'ye ve secret'lara eriştiyse, bunun zaten ihlal sayılması gerektiğini düşünüyorum
    Erişim ihtimali varsa ihlal olarak kabul edilmelidir

    • AWS kaynak erişim logları varsa ve yetkiler geri alınmadan önce erişim izi yoksa, verinin güvende olduğu söylenebilir
  • Kötü amaçlı yazılım çalıştıktan sonra kaynağın izini sürmek neredeyse imkânsızdır
    pnpm install da normal şekilde tamamlandığı için tespit etmek zordur
    Sentinel One veya CrowdStrike gibi bir EDR olsaydı soruşturma için daha fazla ipucu olurdu

    • EDR olsaydı Trufflehog saldırı zincirini tespit etmiş ya da engellemiş olma ihtimali yüksekti
  • “Toplam 669 repo klonladı” kısmı dikkatimi çekti
    100'den az çalışanı olan bir şirketin 600'den fazla repo sahibi olması normal mi diye merak ettim

    • Tamamen normal. Repo'lar evcil hayvan değil, besi hayvanıdır
    • Bizim organizasyon 7 kişilik ama GitHub'da 365 repo'muz var
      Repo sayısını ekip büyüklüğünden çok şirket yaşı ve proje ömrü etkiliyor
    • Mikroservis seven bir mimarınız varsa sonuç böyle olur
  • pnpm zaten preinstall gibi lifecycle script'lerini otomatik çalıştırmayı durdurmuştu, sanırım eski sürüm kullanılmış
    İlgili PR'a bakın

    • Yazının sonunda en güncel major sürüme yükselttiklerinden bahsediliyor
    • Ben de pnpm kullanmanın ana nedeninin bu olduğunu sanıyordum, o yüzden kafam karıştı
    • Sonuçta eski bir paket yöneticisiyle bağımlılık güncellemesi yaptılarsa, bu onların sorumluluğu
    • Projenin kendisinde de bir postinstall script'i olabilir
      pnpm bağımlılıkların script'lerini engelliyor ama proje düzeyindeki script'leri hâlâ çalıştırıyor
  • Şeffaf bir post-mortem paylaşımı için teşekkürler
    Bu tür vakalar sektörün tamamı için önemli
    Saldırı trafiğinin normal geliştirici trafiğinden ayırt edilip edilemediğini merak ediyorum
    Biz de geliştirme ortamında egress filtering'i sıkılaştırmaya çalışıyoruz ama npm install sık sık bozulduğu için zorlanıyoruz

    • GitHub organizasyonlarının IP allow list özelliği, bu tür saldırılara karşı savunmada yardımcı olabilir gibi görünüyor
  • Kişisel dizüstü bilgisayarımda git güvenliğini düşünüyorum
    Şu anda SSH anahtarlarını yerelde tutup push yapıyorum
    Yönetici yetkim de var, dolayısıyla riskli. Bunu daha güvenli hâle getirmenin bir yolunu merak ediyorum

    • SSH anahtarları ve Git imzalarını yönetmek için 1Password kullanmayı, ayrıca push/pull için GitHub OAuth veya CLI oturumu kullanmayı öneririm
      Böylece imzalama anahtarlarıyla erişim anahtarlarını ayırabilirsiniz ve yönetici hesabını da ayrı yönetebilirsiniz
      İlgili belgeler: 1Password SSH Agent, Git Commit Signing, GitHub OAuth, GitHub CLI Login
    • Ben SSH özel anahtarını TPM içinde saklıyorum ve PKCS11 ile SSH agent üzerinden kullanıyorum
      Anahtarın dışarı sızdırılamaması avantaj ama kötü amaçlı yazılım makinemde çalışıyorsa yine de risk var
      Linux örneği, macOS örneği
    • Dizüstü bilgisayar enfekte olursa savunma kalmaz
      TPM veya Yubikey ile işi biraz zorlaştırabilirsiniz ama tam koruma mümkün değil
      Yönetici işleri için ayrı, özel bir makine kullanmak daha güvenli
    • GPG anahtarını Yubikey'e koyup SSH kimlik doğrulamasını gpg-agent ile yapmak da bir seçenek
      push veya commit sırasında PIN girerek kilidi açıyorsunuz
    • main dalına doğrudan push'u engelleyip MFA'yı zorunlu kılarsanız, saldırganın dağıtım dalına hemen erişmesi zorlaşır
  • Torvalds adını taşıyan commit'ler, enfeksiyondan sonra sık görülen bir işaret (signature) idi
    Microsoft'un resmî analiz yazısında da buna değiniliyor
    Bu solucan çok gürültülüydü ve bazı saldırganlar ele geçirilmiş kimlik bilgilerini kullanarak özel repo'ları herkese açtı veya readme'leri değiştirerek bunu tanıtım amaçlı kötüye kullandı

  • Saldırgan yıkıcı eylemler olmadan sessizce sadece veri sızdırmış olsaydı, bunun tespit edilip edilemeyeceğini merak ediyorum