1 puan yazan GN⁺ 2 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • 2026-05-11 19:20~19:26 UTC arasında saldırgan, 42 @tanstack/ npm paketi genelinde 84 kötü amaçlı sürüm yayımladı
  • Saldırı zinciri, pull_request_target “Pwn Request”, GitHub Actions cache kirlenmesi ve runner belleğinden OIDC token çıkarılmasını birleştirdi
  • npm token’ları ve publish workflow’u ele geçirilmedi veya bozulmadı; kötü amaçlı kod, registry’ye doğrudan OIDC trusted publisher yetkisiyle POST gönderdi
  • Etkilenen sürümler yüklendiyse AWS, GCP, Kubernetes, Vault, GitHub, npm, SSH kimlik bilgileri açığa çıkmış olabilir ve değiştirilmeleri gerekir
  • Etkilenen tüm sürümler deprecated olarak işaretlendi, npm security ile tarball kaldırma işlemi yürütüldü ve takip sorunu ile GitHub Security Advisory yayımlandı

Olay Özeti

  • 2026-05-11 19:20~19:26 UTC arasında saldırgan, 42 @tanstack/* npm paketi genelinde 84 kötü amaçlı sürüm yayımladı
  • Saldırı zinciri, pull_request_target “Pwn Request” deseni, fork↔base güven sınırını aşan GitHub Actions cache kirlenmesi ve GitHub Actions runner süreç belleğinden OIDC token çıkarılmasını birleştirdi
  • npm token’larının çalınmadığı ve npm publish workflow’unun kendisinin de tehlikeye atılmadığı doğrulandı
  • Kötü amaçlı sürümler, harici araştırmacı ashishkurmi tarafından stepsecurity üzerinden 20 dakika içinde herkese açık şekilde tespit edildi
  • Etkilenen tüm sürümler deprecated olarak işaretlendi ve npm security ile birlikte registry’den tarball kaldırma işlemi başlatıldı
  • 2026-05-11 tarihinde etkilenen sürümleri yükleyen kullanıcılar, kurulum yapılan host üzerinde erişilebilen AWS, GCP, Kubernetes, Vault, GitHub, npm, SSH kimlik bilgilerini değiştirmelidir
  • Takip sorunu TanStack/router#7383, GitHub Security Advisory ise GHSA-g7cv-rxg3-hmpx

Etki Kapsamı

  • Etkilenen paketler

    • Etki alanı 42 paket ve 84 sürümü kapsıyor; paket başına 2 sürüm yaklaşık 6 dakikalık arayla yayımlandı
    • Tam liste takip sorununda yer alıyor
    • Etkilenmediği doğrulanan ürün ailesi @tanstack/query*, @tanstack/table*, @tanstack/form*, @tanstack/virtual*, @tanstack/store, @tanstack/start meta paketidir
    • @tanstack/start-*, doğrulanmış etkilenmeme listesine dahil değildir
  • Kötü amaçlı kodun davranışı

    • Geliştirici veya CI ortamı etkilenen sürümler için npm install, pnpm install, yarn install çalıştırdığında npm, kötü amaçlı optionalDependencies girdisini çözümler ve fork ağındaki orphan payload commit’ini çeker
    • Ardından prepare lifecycle script’i çalışır ve etkilenen tarball içine gizlenmiş yaklaşık 2.3MB boyutundaki obfuscated router_init.js devreye girer
    • Kötü amaçlı script; AWS IMDS/Secrets Manager, GCP metadata, Kubernetes service-account token, Vault token, ~/.npmrc, GitHub token, gh CLI, .git-credentials, SSH private key gibi yaygın konumlardan kimlik bilgilerini toplar
    • Çalınan veriler Session/Oxen messenger file-upload network üzerinden dışarı sızdırılır; hedefler filev2.getsession.org, seed{1,2,3}.getsession.org adresleridir
    • Bu ağ uçtan uca şifreli olduğundan ve saldırgan kontrolünde bir C2 bulunmadığından, ağ temelli azaltma önlemleri yalnızca IP/domain engellemesiyle sınırlıdır
    • Kendi kendine yayılma mantığı, registry.npmjs.org/-/v1/search?text=maintainer:<user> ile kurbanın bakımını yaptığı diğer paketleri listeledikten sonra aynı enjeksiyon yöntemiyle yeniden yayımlar
    • Payload, npm install lifecycle’ının bir parçası olarak çalıştığından, 2026-05-11 tarihinde etkilenen sürümleri yükleyen host’lar potansiyel olarak tehlikeye atılmış kabul edilmelidir

Zaman Çizelgesi

  • Saldırı öncesi: cache zehirleme aşaması

    • 2026-05-10 17:16 UTC'de saldırgan, TanStack/router fork'u olan github.com/zblgg/configuration'ı oluşturdu ve fork listesi aramalarından kaçınmak için adını değiştirdi
    • 2026-05-10 23:29 UTC'de, sahte kimlik claude <claude@users.noreply.github.com> ile kötü amaçlı 65bf499d16a5e8d25ba95d69ec9790a6dd4a1f14 commit'i fork'a yazıldı
    • Bu commit, yaklaşık 30.000 satırlık bundle JS payload'ı olan packages/history/vite_setup.mjs dosyasını ekledi ve push event'inin CI'ını bastırmak için commit mesajına [skip ci] ekledi
    • 2026-05-11 yaklaşık 10:49 UTC'de zblgg, TanStack/router main hedefli, başlığı “WIP: simplify history build” olan PR #7378'i açtı
    • bundle-size.yml ve labeler.yml her ikisi de PR için pull_request_target ile otomatik çalıştı ve pull_request_target, ilk katkıcı onay kapısını baypas ettiği için ek onay gerekmedi
    • pull_request kullanan pr.yml, onay beklediği için engellendi ve çalışmadı
    • 2026-05-11 11:01~11:11 UTC arasında zblgg, PR head'ine birkaç kez force-push yaparak ek pull_request_target çalıştırmalarını tetikledi
    • 2026-05-11 11:11 UTC'de kötü amaçlı 65bf499d commit'i PR head'ine geldi ve bundle-size.yml içindeki benchmark-pr job'ı refs/pull/7378/merge'ü checkout ettikten sonra pnpm install ve pnpm nx run @benchmarks/bundle-size:build çalıştırdı; bu sırada vite_setup.mjs devreye girdi
    • 2026-05-11 11:29 UTC'de Linux-pnpm-store-6f9233a50def742c09fde54f56553d6b449a535adf87d4083690539f49ae4da11 adlı 1,1 GB'lık GitHub Actions cache'i TanStack/router'a kaydedildi
    • Bu cache, refs/heads/main kapsamına kaydedildi ve sonraki main push'unda release.yml'in sorgulayacağı anahtarla eşleşecek şekilde yapılandırıldı
    • 2026-05-11 11:31 UTC'de saldırgan, görünür PR'ı 0 dosyalı no-op gibi göstermek için PR'ı o andaki main HEAD'i b1c061af durumuna geri aldı; aynı dakika içinde PR'ı kapatıp branch'i sildi, ancak zehirlenmiş cache kaldı
  • Tetiklenme: yayımlama aşaması

    • 2026-05-11 19:15 UTC'de Manuel, PR #7369'u merge ederek main push'unu tetikledi; release.yml workflow run 25613093674 19:15:44'te başladı ve ardından başarısız oldu
    • 2026-05-11 19:20:39 UTC'de npm registry, @tanstack/history@1.161.9 ve aynı gruptaki 41 sibling package için publish aldı
    • Toplamda 42 paket ve yaklaşık 84 sürüm yayımlandı, ancak bu tam saniyede görünenler yaklaşık yarısıydı; kalanı ikinci run'da yayımlandı
    • Publish kimlik doğrulaması, TanStack/router release.yml@refs/heads/main için OIDC trusted-publisher binding ile yapıldı, ancak bu işlem test başarısızlığı nedeniyle atlanan workflow'un Publish Packages adımında gerçekleşmedi
    • Gerçek yayımlayıcı, test/cleanup aşamalarında çalışan malware idi; id-token: write izniyle bir OIDC token mint edip doğrudan registry.npmjs.org'a POST attı
    • 2026-05-11 19:20:47 UTC'de run 25613093674, failure durumuyla tamamlandı
    • 2026-05-11 19:16 UTC'de Manuel, PR #7382'yi merge ederek ikinci main push'unu oluşturdu ve 19:16:22'de workflow run 25691781302 başladı
    • İkinci run da aynı zehirlenmiş cache'i restore etti ve 2026-05-11 19:26:14 UTC'de @tanstack/history@1.161.12 dahil paket başına ikinci sürüm seti aynı OIDC mekanizmasıyla yayımlandı
    • 2026-05-11 19:26:20 UTC'de run 25691781302 de failure durumuyla tamamlandı
  • Tespit ve müdahale

    • 2026-05-11 yaklaşık 19:50 UTC'de dış araştırmacı carlini, kötü amaçlı optionalDependencies fingerprint'i ve paket listesini içeren issue #7383'ü açtı
    • İlk listede 42 paketin 14'ü vardı ve araştırmacı npm security'yi de doğrudan bilgilendirdi
    • 2026-05-11 yaklaşık 20:00 UTC'de Manuel, #7383 içinde olayı doğruladı ve müdahaleyi başlattı
    • 2026-05-11 yaklaşık 20:10 UTC'de Manuel, kullanıcı makinelerinin etkilenmiş olma ihtimaline karşı diğer ekip üyelerinin GitHub push izinlerini kaldırdı
    • 2026-05-11 yaklaşık 20:30 UTC'de Tanner, tam IOC listesini ve registry tarafındaki tarball kaldırma talebini security@npmjs.com adresine gönderdi ve npm üzerinden resmî malware raporu sundu
    • 2026-05-11 yaklaşık 21:00 UTC'de 295 adet @tanstack/* paketinin tamamı taranarak kapsamın 42 paket ve 84 sürüm olduğu doğrulandı
    • Tanner, etkilenen 84 paketin tamamı için npm deprecation sürecini başlattı ve @tan_stack ile maintainer'lar Twitter/X, LinkedIn ve Bluesky'da kamuya açık duyurular yaptı
    • 2026-05-11 21:30 UTC'de bundle-size.yml içindeki pull_request_target cache zehirleme vektörü ve zblgg/configuration fork'u tespit edildi
    • Tüm TanStack/* GitHub repository'lerindeki cache girdileri API üzerinden kaldırıldı
    • Hardening PR'ı merge edildi; bundle-size.yml yeniden yapılandırıldı, repository_owner guard eklendi ve third-party action ref'leri SHA'ya sabitlendi
    • Resmî GitHub Security Advisory yayımlandı ve CVE talep edildi

Temel neden

  • Üç zafiyetin birleşimi

    • Saldırı için üç zafiyetin de tamamı gerekliydi; bunlardan yalnızca biri tek başına yeterli değildi
    • Her zafiyet, diğerinin güven sınırını birbirine bağlıyordu: fork PR kodu base repository cache'ine geçiyor, base repository cache'i release workflow runtime'ına geçiyor ve release workflow runtime'ı da npm registry yazma yetkisine ulaşıyordu
  • pull_request_target “Pwn Request” deseni

    • bundle-size.yml, fork PR için pull_request_target ile çalıştırıldı; bu trigger context içinde fork'un PR merge ref'i checkout edildikten sonra build çalıştırıldı
    • Temel yapı şöyleydi
    on:
      pull_request_target:
        paths: ['packages/**', 'benchmarks/**']
    
    jobs:
      benchmark-pr:
        steps:
          - uses: actions/checkout@v6.0.2
            with:
              ref: refs/pull/${{ github.event.pull_request.number }}/merge # fork's merged code
    
          - uses: TanStack/config/.github/setup@main # transitively calls actions/cache@v5
    
          - run: pnpm nx run @benchmarks/bundle-size:build # executes fork-controlled code
    
    • Workflow yazarı, comment-pr job'u ile benchmark-pr job'unu ayırarak güven sınırlarını bölmeye çalışmıştı ve YAML comment içinde benchmark-pryi “untrusted with read-only permissions” olarak tutma niyeti belirtilmişti
    • Ancak actions/cache@v5 içindeki post-job save, permissions: ile engellenmez ve cache write işlemi workflow GITHUB_TOKEN'ını değil, runner iç token'ını kullanır
    • Bu nedenle permissions: contents: read ayarı cache mutation'ını engelleyemedi
    • Cache scope'u repository düzeyindedir ve base repository cache scope'unu kullanan pull_request_target çalıştırmaları ile main push'ları bunu paylaşır
    • Base repository cache scope'unda çalışan bir PR, daha sonra main üzerindeki production workflow'un restore edeceği cache entry'yi zehirleyebilir
  • GitHub Actions cache zehirleme

    • Kötü amaçlı vite_setup.mjs, normal release.yml workflow'unun hesaplayıp sorgulayacağı pnpm-store key'ine uygun şekilde veri yazmak için tasarlanmıştı
    • Hedef key, Linux-pnpm-store-${hashFiles('**/pnpm-lock.yaml')} biçimindeydi
    • benchmark-pr job'u bittiğinde actions/cache@v5 post-step'i zehirlenmiş pnpm store'u tam olarak bu key ile kaydetti
    • Ardından main push'unda release.yml çalışınca Setup Tools adımı tasarlandığı gibi zehirlenmiş entry'yi restore etti
    • Bu saldırı türü, Adnan Khan'ın 2024'te belgelediği GitHub Actions cache poisoning sınıfına giriyor; bu, yalnızca TanStack'e özgü bir bug değil, bilinçli hafifletme gerektiren bir GitHub Actions tasarım sorunudur
  • Runner belleğinden OIDC token çıkarma

    • release.yml, npm OIDC trusted publishing için gerekli olduğundan meşru şekilde id-token: write tanımlıyordu
    • Zehirlenmiş pnpm store runner'a restore edildiğinde, saldırganın kontrolündeki binary diskte mevcut hale gelir ve build adımı sırasında çağrılır
    • Bu binary, /proc/*/cmdline ile GitHub Actions Runner.Worker sürecini bulur ve /proc/<pid>/maps ile /proc/<pid>/mem dosyalarını okuyarak worker belleğini dump eder
    • Ardından runner'ın id-token: write ayarı kapsamında lazy mint ettiği OIDC token'ı bellekten çıkarır
    • Çıkarılan token ile registry.npmjs.org adresine doğrudan POST isteği kimlik doğrulaması yapılarak gönderilir ve workflow içindeki Publish Packages adımı tamamen atlanır
    • Bu bellekten çıkarma yöntemi, 2025 Mart'taki tj-actions/changed-files compromise olayında kullanılan yöntemle aynıdır ve attribution comment içeren aynı Python script kullanılmıştır
    • Saldırgan yeni bir teknik icat etmedi; kamuya açık araştırmaları yeniden birleştirdi
  • Neden her bir unsur tek başına yeterli değildi

    • pull_request_target tek başına label veya comment gibi güvenilir işler için kullanılabilir
    • Zaten ele geçirilmiş bir dependency içindeki cache poisoning, tek başına ek bir publish aracı olmadan yeterli değildir
    • OIDC token extraction ise runner üzerinde önceden var olan code execution gerektirir

Tespit ve IOC

  • Tespit yolu

    • Tespit içeriden değil, dışarıdan yapıldı
    • carlini, publish işleminden yaklaşık 20 dakika sonra issue #7383'ü açarak tam teknik analizi paylaştı
    • Tanner, war room'u başlattıktan hemen sonra durumu doğrulamak için Socket.dev'den bir telefon aldı
  • Downstream maintainer'lar ve güvenlik araçları için fingerprint

    • @tanstack/* paket manifest'lerinde aşağıdaki optionalDependencies girdisi temel IOC'dir
    "optionalDependencies": {
      "@tanstack/setup": "github:tanstack/router#79ac49eedf774dd4b0cfa308722bc463cfe5885c"
    }
    
    • Dosya IOC'si package root altındaki router_init.js dosyasıdır; yaklaşık 2.3MB boyutundadır ve "files" içine dahil edilmemiştir
    • Cache key, Linux-pnpm-store-6f9233a50def742c09fde54f56553d6b449a535adf87d4083690539f49ae4da11'dir
    • İkinci aşama payload URL'leri https://litter.catbox.moe/h8nc9u.js ve https://litter.catbox.moe/7rrc6l.mjs'dir
    • Veri sızdırma ağı filev2.getsession.org ve seed{1,2,3}.getsession.org'dur
    • Sahte commit kimliği claude <claude@users.noreply.github.com> şeklindedir; bu gerçek Anthropic Claude değil, manipüle edilmiş bir GitHub no-reply e-postasıdır
    • Gerçek saldırgan hesapları zblgg id 127806521 ve voicproducoes id 269549300'dür
    • Saldırgan fork'u github.com/zblgg/configuration olup, TanStack/router fork'u arama tespitinden kaçınmak amacıyla yeniden adlandırılmıştır
    • Fork network içindeki orphan payload commit'i 79ac49eedf774dd4b0cfa308722bc463cfe5885c'dir
    • Kötü amaçlı publish'i gerçekleştiren workflow run'ları github.com/TanStack/router/actions/runs/25613093674 attempt 4 ve github.com/TanStack/router/actions/runs/25691781302'dir

Çıkarılan dersler

  • İyi gidenler

    • Dış araştırmacılar olayı yaklaşık 20 dakika içinde tespit edip tüm teknik ayrıntılarla birlikte raporladı
    • maintainer ekibi birden fazla time zone boyunca anında koordinasyon sağladı
    • Tespit topluluğu birkaç saat içinde net ve herkese açık IOC kalıplarını elde etti
  • İyileştirilmesi gerekenler

    • İç alerting yoktu ve compromise durumu üçüncü taraflardan öğrenildi
    • Kendi publish monitoring sistemimize ihtiyaç var; ayrıca bu tür sorunları hızlı tespit edebilen ekosistem güvenliği araştırma şirketleriyle daha yakın çalışıp feedback loop'u daraltmayı planlıyoruz
    • pull_request_target workflow'su uzun zamandır tehlikeli bir kalıp olarak biliniyordu ancak audit edilmemişti
    • Third-party action'ların floating ref'leri olan @v6.0.2, @main, bu olaydan bağımsız olarak sürekli bir supply-chain risk oluşturuyor
    • npm'nin “dependent varsa unpublish yapılamaz” politikası nedeniyle etkilenen paketlerin neredeyse tamamında unpublish mümkün olmadı
    • Registry tarafında tarball kaldırma işlemi için npm security'ye bağımlı kalındı ve bu nedenle kötü amaçlı tarball'ların kurulabilir durumda kalma süresi birkaç saat daha uzadı
    • npm scope içindeki 7 maintainer listesi, aynı blast radius için 7 ayrı credential-theft target anlamına geliyor
    • OIDC trusted-publisher binding'de publish bazında review yok; bir kez ayarlandığında workflow içindeki herhangi bir code path publish edebilen bir token mint edebiliyor
    • Gerekli alternatifler, manuel review içeren kısa ömürlü classic token'lara geçmek veya beklenmeyen workflow step'lerinden yapılan publish işlemlerini tespit edecek provenance-source-verification eklemek
  • Şanslı olunan noktalar

    • Saldırgan, testleri bozan bir payload seçtiği için normal publish step'i skip edildi ve daha temiz görünen bir tarball üretilmedi
    • Bu sayede saldırı yeterince gürültülü hale geldi ve hızla tespit edildi
    • Daha dikkatli bir saldırgan testleri bozmasaydı birkaç saat daha sessizce publish yapabilirdi
    • Saldırgan, attribution comment içeren herkese açık bir memory-dump script'ini yeniden kullandı; yeni kod yazmaması IOC matching'i hızlandırdı

Açık kalan sorular

  • bundle-size.yml içindeki Setup Tools step'inin gerçekten actions/cache@v5 çağırıp çağırmadığı doğrulanmalı
  • PR #7378 için pull_request_target çalıştırmalarından birinin post-job log'u okunup doğrulanmalı; örnek run id 25666610798
  • Force-push ile kaybolmadan önce ilk PR head commit'inde ne olduğu doğrulanmalı; GitHub reflog'unda kalmış olabilir
  • Kötü amaçlı commit'in fork'un git object store'una nasıl girdiği, doğrudan bir git push ile mi yoksa audit-log entry bırakacak GitHub web UI oluşturmasıyla mı olduğu doğrulanmalı
  • voicproducoes hesabının gerçek bir hesap mı yoksa bir sock puppet mı olduğu, etkinlik geçmişiyle karşılaştırılarak doğrulanmalı
  • 6 adet yinelenen linux-npm-store-* girdisi gibi görünen npm cache'in de kirlenip kirlenmediği ve gerçekten kullanılıp kullanılmadığı doğrulanmalı
  • Saldırı için Nx Cloud gerekip gerekmediği veya yalnızca GitHub Actions cache ile de çalışıp çalışmayacağı doğrulanmalı
  • TanStack/router fork network'ü içinde orphan payload commit'ini barındıran başka fork'ların belirlenip belirlenemeyeceği doğrulanmalı
  • Başka bir fork bu commit'i barındırıyorsa github:tanstack/router#79ac49ee... erişilebilirliği korunur ve cleanup daha zor hale gelir
  • router, query, table, form, virtual gibi diğer TanStack repo'larının aynı bundle-size.yml tarzı kalıbı kullanıp kullanmadığına dair audit gerekli
  • Publish window sırasında etkilenen sürümleri gerçekten indiren kullanıcı sayısı npm support'tan alınmalı
  • 7 maintainer'ın makinelerinin ayrıca compromise olup olmadığı doğrulanmalı
  • Kötü amaçlı publish'de maintainer npm token'ı kullanılmadı, ancak maintainer makineleri self-propagation logic'in ikincil hedefi olabilir

Referanslar

1 yorum

 
GN⁺ 2 시간 전
Hacker News yorumları
  • Token iptal ederken dikkatli olmak gerekiyor. Payload'ın dead-man's switch mekanizmasını ~/.local/bin/gh-token-monitor.sh içine kurduğu ve Linux'ta bir systemd kullanıcı servisi olarak, macOS'ta ise LaunchAgent com.user.gh-token-monitor olarak kaydettiği görülüyor
    Çalınan token ile her 60 saniyede bir api.github.com/user poll ediliyor, token iptal edilip HTTP 40x dönünce de rm -rf ~/ çalıştırılıyor
    https://github.com/TanStack/router/issues/7383#issuecomment-...

    • Gerçekçi olmak gerekirse, zararlı yazılım yüklendiyse zaten bilgisayarı tamamen sıfırlamanız gerekir
    • Vay canına. Tam bir karşılıklı garantili yıkım durumu
      Önümüzdeki 5 yılda yazılım dünyası gerçekten çok sertleşecek gibi görünüyor ve air-gapped sistemler çok daha önemli hale gelecek
    • Aslında her zaman yedekleme yapılandırmış olmalıydınız, ama bu olay yüzünden insanlar yedek almaya başlarsa en azından iyi bir yanı olur
  • @mistralai/mistralai npm paketi de bu worm'ün parçası olarak ele geçirilmiş
    https://github.com/mistralai/client-ts/issues/217
    Şu anda npm kayıt defterinden kaldırılmış durumda

  • Ne yazık ki bu, yalnızca Trusted Publishing'in CI içinde güvenli dağıtım yapmak için yeterli olmadığını gösteren bir kanıt gibi görünüyor. CI pipeline'ının içindeki bir saldırgan ya da çalınmış depo yönetici yetkileri varsa kolayca dağıtım yapılabiliyor
    Bu yeni bir bilgi değil ve Trusted Publishing de bunu garanti etmek için tasarlanmadı, ama yerel dağıtım ve iki aşamalı kimlik doğrulamadan Trusted Publishing'e geçince, CI ihlali üzerinden böyle bir saldırı yolu ortaya çıkıyor. Yani yerelde çalışırken npm publish'i durduran ikinci faktör ortadan kalkmış oluyor
    Olayların mevcut akışına göre saldırgan CI/CD pipeline'ını ele geçirmiş ve npm publish için ikinci bir faktör olmadığı için OIDC token'ını çalıp dağıtımı tamamlamış gibi görünüyor. İlginç ama ayrı bir nokta olarak, dağıtım işi aslında başarısız olmuş fakat kötü amaçlı commit içindeki payload'ın workflow'nun OIDC token'ı ile kendi kendine dağıtım yapabildiği anlaşılıyor
    İstenen şey, uzun ömürlü token olmayan Trusted Publisher modelini korurken GitHub dışındaki ikinci faktörün de kaldığı bir CI dağıtımı. Yani npm tarafında birinin iki aşamalı kimlik doğrulama ile artifact'i gerçekten herkese açık hale yükseltmesi gereken aşamalı dağıtım lazım
    Eğer dağıtım yalnızca GitHub güven modelinin içinde mümkünse, depo yönetici token'ını ele geçiren ya da pipeline'a kötü amaçlı kod sokan herkes dağıtımı rahatça tamamlayabilir. GitHub bağlamının dışında gerçek bir ikinci faktör varsa, depoyu bozabilir ya da kötü kod ekleyebilirler ama kayıt defteri için ikinci faktör olmadan dağıtım yapamazlar

    • Yarı popüler bir paketim var ve hâlâ yerel dağıtım ve iki aşamalı kimlik doğrulama kullanıyorum. Trusted Publishing fazla karmaşık görünüyor ve sürekli hack'leniyormuş gibi duruyor; bizim bunu güvenle işletebilmemiz için fazla karmaşık olabilir, belki de baştan yeniden tasarlanması gerekir
    • Hâlâ Trusted Publishing'in büyük bir iyileştirme olduğunu düşünüyorum, ama bir sürümü gerçekten herkese açık olarak işaretlerken ikinci faktör isteme fikri iyi. Bu, bu tür CI worm'lerini çalıştırmayı çok zorlaştırır
    • YubiKey benzeri bir şeyle dokunarak imzalama yapmak isterim. Bulutun kimlik bilgilerini benim yerime yönetmesine güvenme fikri baştan hata gibi geliyor
    • astral blog yakın zamanda Trusted Publishing kullanırken de nasıl release gate konulduğunu, yani release workflow'suna manuel onay nasıl eklendiğini gösterdi. Ne yazık ki NPM/PyPI/Rubygems Trusted Publishing belgelerinde bu olasılıktan hiç söz edilmiyor ve varsayılan olarak da sunulmuyor
    • İnsanların bu tür tedarik zinciri saldırılarında Trusted Publishing'in ne fark yarattığını neden söylediğini hiç tam anlayamadım
  • Sonradan analiz: https://tanstack.com/blog/npm-supply-chain-compromise-postmo...

    • TanStack'in sonradan analizi için teşekkürler, ancak npm ekosisteminin tamamı açısından güvenlik sorunu hâlâ süren bir endişe değil mi diye düşünüyorum
      TanStack paketlerini çekmiş ya da içermiş olabilecek alt paketlerin güvenli kabul edilebileceğine dair bir kanıt var mı merak ediyorum
  • postinstall script'leri ölümcül. Herkes pnpm kullanmalı
    FORK'a push edilmiş “sahipsiz” bir commit'in npm istemcisinde böyle bir şeye yol açabilmesi akıl alır gibi değil. Bence GitHub'ın da burada büyük sorumluluğu var. Kötü niyetli bir fork'taki commit'in, GitHub'ın paylaşımlı nesne depolaması üzerinden meşru depoyla ayırt edilemeyen bir URI ile erişilebilir olması tam anlamıyla çılgınca bir tasarım

    • Uygulamayı güncellenmiş bağımlılıklarla çalıştırdığınız anda o kod zaten çalışıyor. root ya da non-root olması da önemli değil; önemli şeylere uygulamayı çalıştıran kullanıcı yetkileri ile erişilebiliyor
    • Bunun nasıl GitHub için bir P0 kesintisi sayılmadığını anlamıyorum. Bunu açıklayabilecek biri var mı?
      İlk okuduğumda “fork” kelimesini yanlış kullandıklarını ve aslında resmi depodaki bir branch'ten söz ettiklerini sanmıştım. Bunun gerçek olamayacağını düşündüm ama meğer oluyormuş
  • https://tanstack.com/blog/npm-supply-chain-compromise-postmo...
    TanStack bu olayla ilgili sonradan analizini az önce yayımladı

  • npm ortamını güvenli yapılandırmanız için bir hatırlatma
    https://gajus.com/blog/3-pnpm-settings-to-protect-yourself-f...
    Birkaç ayarla büyük sorunlar azaltılabilir

    • npm v11 ve sonrasında allow-git=none da var: https://github.blog/changelog/2026-02-18-npm-bulk-trusted-pu...
    • Bu yazı npm'in minimum sürüm yaşı konusunda hatalı değil mi diye düşünüyorum. 1) Ayarın adı min-release-age. 2) Nedense dakika yerine gün cinsinden yapılmış: https://docs.npmjs.com/cli/v11/using-npm/config#min-release-...
      Bağımlılık yöneticisi alanının tamamen gereksiz şekilde parçalandığını düşünüyorum
    • Minimum yaşı 7 gün yapmak npm tedarik zinciri zafiyetlerini “asla” yaşamayacağınız anlamına gelmez demek daha doğru olur
    • Tüm bağımlılıkların mutlaka sabitlenmesi gerekir
      Paket sürümü bağımlılıkları ^1.0.0 gibi ya da hatta "*" ise, daha fazla okumayı bırakıp hemen güvenli sürümlere sabitlemelisiniz
  • Claude ile aceleyle yapıldı; yayılmayı azaltmaya yardımcı olsun istedim. Elbette kendiniz doğrulamalısınız ama bahsi geçen ele geçirilmiş paketlerin makinede olup olmadığını tarıyor: https://github.com/PaulSinghDev/tanstack-shai-hulud-fix

  • Artık herkesin her projeyi ayrı bir VM içinde çalıştırması gereken noktaya gelmiş olabiliriz
    Son dönemdeki yerel yetki yükseltme açıklarına bakınca yalnızca Docker kesinlikle yeterli değil. Zaten container'lar başlı başına ana güvenlik sınırı olarak tasarlanmadı

    • Devcontainers, bu tür “izole geliştirme ortamı” fikrinin en bilinen biçimi, ama tam bir VM değil ve bu olayda da tam koruma sağlamıyor. Çünkü GitHub kimlik bilgileri container'ın içine otomatik olarak giriyor
      Container içinde erişmeniz gereken başka bulut servisleri varsa, bu kimlik bilgisi hırsızı onları da alacaktır. Yine de etki alanını küçülttüğü için en azından bir iyileştirme sağlar
    • QubesOS doğru yöne gidiyor. Kök seviyede birden çok VM ve katmanlı güvenlik istemeye başlıyorsunuz
    • Container kullanacaksanız, her container için bir VM de kullanabilirsiniz. Rastgele bir Kubernetes hizmeti yerine her şeyi VM'lerde çalıştırdığım için son birkaç haftadır oldukça rahatım
    • Neyse ki C ve C++ gibi daha güvenli dil ekosistemlerini kullanan projeler bu tür sorunlardan uzak :-)
  • Vay, yine çok büyük bir paket. Axios ve LiteLLM ele geçirildikten sonra paylaştığım kamu yararı duyurusunu tekrar paylaşıyorum. Lifecycle script'leri ile ilgili kısım burada da geçerli
    npm/bun/pnpm/uv artık paketler için minimum sürüm yaşı ayarını destekliyor. ~/.npmrc içine ignore-scripts=true da ekledim; analizlere göre tek başına bu bile zafiyeti hafifletebilirdi. bun ve pnpm varsayılan olarak lifecycle script'lerini çalıştırmıyor
    Minimum sürüm yaşını global olarak 7 gün ayarlamak için şunları kullanabilirsiniz
    ~/.config/uv/uv.toml
    exclude-newer = "7 days"
    ~/.npmrc
    min-release-age=7 # days
    ignore-scripts=true
    ~/Library/Preferences/pnpm/rc
    minimum-release-age=10080 # minutes
    ~/.bunfig.toml
    [install]
    minimumReleaseAge = 604800 # seconds
    Global ayarı geçersiz kılmanız gerekirse CLI flag'lerini kullanabilirsiniz
    npm install --min-release-age 0
    pnpm add --minimum-release-age 0
    uv add --exclude-newer "0 days"
    bun add --minimum-release-age 0
    Bir şey daha ekleyeyim: bağımlılıklar için bekleme süresini yaygın biçimde uygulamanın zafiyetlerin fark edilmesini geciktireceği ya da bunun bir tür bedavacılık olduğu yönünde bir endişe var gibi görünüyor ama buna katılmıyorum. Bağımlılık bekleme süresiyle takas edilen şey zaman tercihi ve her zaman benden daha yüksek zaman tercihine sahip insanlar olacaktır
    0: https://news.ycombinator.com/item?id=47582220
    1: https://news.ycombinator.com/item?id=47513932

    • Katılıyorum. Bu ayarları son iki dalga gelmeden önce, mart ayında etkinleştirmiş olmama sevindim. Ek olarak depoya lockfile commit etmek ve yeni bağımlılıklar eklerken dikkatli olmak gerekiyor
      Beklenmedik değişikliklerden kaçınmak için pnpm install --frozen-lockfile kullanabilirsiniz. min-release-age ayarlamadıysanız, etkilenen paketleri transitive dependency'ler üzerinden de çekebileceğinizi unutmayın. Mümkünse paket yöneticisi sürümünü de sabitlemek iyi olur