← Radar

Konu: Güvenlik3 dk okuma

TanStack nasıl hacklendi? Bir pull request, zehirli önbellek ve çalınan yayın izni

Bu neden önemli?

Açık kaynak projelerin çoğu paketlerini GitHub Actions ile yayımlıyor. Bu olay, sadece paket kurarken değil, projenin kendi CI ayarlarında da tehlike olduğunu gösteriyor. Bir paket yayımlıyorsan aynı açık sende de olabilir.

Ne oldu?

11 Mayıs 2026’da, altı dakika içinde 42 @tanstack/* paketinin 84 zararlı sürümü npm’e yüklendi. TanStack, React dünyasında çok kullanılan Router ve Start gibi kütüphanelerin arkasındaki proje. Yarım saat dolmadan StepSecurity’den bir araştırmacı zararlı sürümleri fark etti ve GitHub’da bildirdi.

Şaşırtıcı olan şu: Hiçbir geliştiricinin şifresi ya da bilgisayarı ele geçirilmedi. TanStack’in olay raporuna göre saldırgan, projenin kendi yayın düzenini (pipeline) birbirine bağlı üç zayıflıkla kullandı.

Bir buçuk ay önce axios da yayın tarafından vurulmuştu, ama başka bir yoldan: Trusted publishing kullanılıyordu, hesapta ise unutulmuş eski bir token duruyordu (axios yazımız).

Üç halkalı zincir

1. Fork’tan gelen kod, yetkili bir iş akışında çalıştı. GitHub Actions’ta pull_request_target adlı bir tetikleyici var. Normal pull_request’ten farkı, iş akışını ana deponun yetkileriyle çalıştırması. TanStack’te paket boyutunu ölçen bir iş akışı bu tetikleyiciyi kullanıyordu ve dışarıdan açılan PR’ın kodunu derliyordu. Saldırgan bir fork açtı, kodun içine 30 bin satırlık zararlı bir dosya koydu ve bir PR gönderdi.

2. Önbellek zehirlendi. Derleme hızlansın diye CI, indirilen paketleri bir önbellekte (cache) saklar. Bu önbellek depo bazında paylaşılıyor. Zararlı kod, pnpm’in paket deposunu tam da ana daldaki yayın iş akışının arayacağı anahtarla önbelleğe yazdı. İş akışında “sadece okuma izni” ayarı vardı ama bu, önbelleğe yazmayı engellemiyordu. Sonra PR eski hâline döndürüldü. Zehir ise önbellekte kaldı.

3. Yayın token’ı hafızadan okundu. Saatler sonra ana dala normal bir değişiklik geldi. Yayın iş akışı önbelleği geri yükledi ve zehirli dosyalar derleme sırasında çalıştı. Bu iş akışı, npm’e şifresiz yayın için OIDC ile kısa ömürlü bir token alabiliyordu (buna “trusted publishing” deniyor). Zararlı kod, çalışan sürecin hafızasından bu token’ı okudu ve paketleri doğrudan npm’e gönderdi.

Zararlı paket ne yapıyordu?

Her zararlı sürüm, bir GitHub commit’ine işaret eden gizli bir bağımlılık ekliyordu. Kurulumda bu bağımlılık bir betik çalıştırıyordu. Betik AWS, Google Cloud, Kubernetes, GitHub ve npm token’larını, SSH anahtarlarını topluyor, sonra kurbanın yönettiği başka paketlere kendini ekleyerek yayılıyordu. Yani bir solucan. StepSecurity’ye göre aynı dalga UiPath ve Mistral paketlerine de ulaştı. Kalıcı olmak için .claude ve .vscode ayarlarına da yerleşiyordu. Bu tekniği Shai-Hulud’un Go’ya sıçradığı yazıda ayrıntılı anlattık.

Paket yayımlıyorsan

  • pull_request_target’ı kaldır ya da çok sıkı sınırla. TanStack bunu tüm depolarından sildi.
  • Yayın iş akışında önbellek kullanma. Ya da sadece okuyan bir önbellek adımı seç.
  • Üçüncü taraf action’ları commit SHA’sına sabitle. @v5 gibi etiketler sonradan değişebilir.
  • İş akışlarını tara. TanStack, GitHub Actions için statik analiz aracı zizmor’u zorunlu kontrol olarak eklemeyi planlıyor.
  • Kendi yayınlarını izle. Raporda açıkça yazıyor: Saldırıyı kendileri değil, dışarıdan biri fark etti.

Sadece paket kuruyorsan

Syntax’ta Wes Bos ve Scott Tolinski, pnpm’in yeni varsayılanlarını öne çıkardı. blockExoticSubdeps ayarı, alt bağımlılıkların git commit’i ya da rastgele bir adres gibi “egzotik” kaynaklardan gelmesini engelliyor. Bu saldırıdaki gizli bağımlılık tam olarak buydu. minimumReleaseAge ise yeni çıkan sürümü bir gün bekletiyor. Nisan sonunda çıkan pnpm 11’de ikisi de varsayılan olarak açık. Diğer önlemleri npm kurulum güvenliği yazısında bulabilirsin.

Sonra ne oldu?

TanStack 15 Mayıs’ta temizlik bitti dedi: Sadece Router/Start deposu etkilenmişti. GitHub da Eylül 2026’da cache-mode ayarını getirdi. Artık her iş akışının önbelleğe okuma mı yazma mı yapabileceğini seçebiliyorsun. pull_request_target gibi düşük güvenli tetikleyicilerde varsayılan “sadece okuma”. Bu, TanStack’teki zincirin ikinci halkasını doğrudan hedefliyor. Aynı pull_request_target tuzağı Şubat’ta bir güvenlik tarayıcısını da vurmuştu; Trivy yazısında anlattık.

Düşün

  • Senin projende dışarıdan gelen bir PR, hangi iş akışlarını tetikliyor? O iş akışları neye erişebiliyor?
  • Paketlerinin npm’de yeni bir sürümü çıktığında bundan haberin oluyor mu?

Videoyu izle

Tıklayınca video YouTube'dan yüklenir; o ana kadar bu sayfa YouTube'a hiçbir istek göndermez.
Kaynaklar (10, İngilizce)

Kendi cümlelerimizle yazılmış bir özettir, çeviri değildir. Tüm kaynaklar yukarıda.

Konu: Güvenlik3 dkVideo: Fireship

Copy Fail: 732 baytlık Python betiği, 2017'den beri neredeyse her Linux'ta root yapıyordu

Linux çekirdeğinin kripto arayüzündeki bir mantık hatası, sıradan bir kullanıcının diskteki dosyaya dokunmadan, bellekteki kopyasını değiştirmesine izin veriyordu. Hatayı Theori'nin araştırmacısı, kendi yapay zekâ tarama aracıyla yaklaşık bir saatte buldu. Birkaç gün içinde gerçek saldırılarda kullanılmaya başladı.