- Araştırmacı, Nixpkgs'deki güvenlik açığını keşfederek Nix ekosisteminin tamamına kötü amaçlı kod enjekte edebilme deneyimini paylaşıyor
- GitHub Actions'ın
pull_request_target tetikleyicisi üzerinden harici katkıcı PR'larında bile hassas yetkilerin ve sırların açığa çıkabildiği yapısal risk açıklanıyor
- Gerçekte editorconfig-checker ve code owners doğrulama işleri içinde komut ekleme ve sembolik bağlantı kullanımıyla yetki yükseltmenin mümkün olduğu kanıtlanıyor
- Açık bulunur bulunmaz Nixpkgs bakım ekibi güvenlik açığını hızla düzeltti, savunmasız iş akışlarını devre dışı bıraktı ve yetki yönetimini yeniden gözden geçirdi
- Kurumların CI/CD altyapısında güvenilmeyen veri ile hassas işlemleri ayırmanın, en az ayrıcalık vermenin ve politikaları güçlendirmenin kritik olduğu vurgulanıyor
Nix ekosisteminin tamamını hack'lemek
Giriş ve arka plan
- Geçen yıl NixCon'da araştırmacı ve çalışma arkadaşı Lexi, Nixpkgs'deki güvenlik açığını sundu
- Keşfedilen bu açık, bir tedarik zinciri saldırısıyla Nix ekosisteminin geneline kötü amaçlı kod enjekte etme ihtimalinin önünü açtı
- Güvenlik açığının tespitinden bildirimine ve müdahalesine kadar her şey sadece bir gün içinde gerçekleşti
- Araştırmacı bu yıl NixCon'a katılamadığı için süreci bu yazıda ayrıntılı biçimde derliyor
GitHub Actions: savunmasız bir hedef
- GitHub Actions, kod depolarında çeşitli otomasyon işleri (CI/CD) çalıştırmayı sağlayan bir sistemdir
- İş akışı dosyalarına erişim yetkisi olan biri kolayca kod ekleyebildiği için, bu yapı tedarik zinciri saldırılarının başlıca hedeflerinden biri hâline geliyor
- İş akışı dosyaları YAML ile yazılır ve çalıştırma amacıyla tasarlanmış bir biçim olmadığından beklenmedik güvenlik açıkları barındırabilir
- Basit bir örnek olarak, koda push atıldığında komut çalıştıran bir iş akışı bulunabilir
Tehlikeli pull_request_target tetikleyicisi
- GitHub Actions içinde birden fazla tetikleyici vardır; bunlardan pull_request_target, normal
pull_requestten önemli ölçüde farklıdır
pull_request_target, fork'lardan gelen PR'larda bile varsayılan olarak read/write yetkisi ve sır erişimi taşıyabilir
- Bu tetikleyicinin yanlış kullanımı, güvenilmeyen harici veriyi hassas yetkilerle bir araya getirir
- GitHub'un resmî belgeleri de bu riski açıkça uyarır
- Araştırmacı, Nixpkgs deposunda
pull_request_target kullanan 14 iş akışını inceledi
editorconfig-checker güvenlik açığı
- İlk bulunan savunmasız iş akışı, editorconfig kurallarını denetlemek için kullanılıyordu
- Değişen dosya listesi hesaplandıktan sonra bu liste
xargs ile editorconfig-checker'a iletiliyordu
xargs komutunun güvenlik uyarıları göz ardı edildiğinde, kötü niyetle tasarlanmış dosya adları (örneğin --help) enjekte edilebilen bir açık ortaya çıkıyor
- Bu sayede editorconfig-checker keyfi biçimde manipüle edilebiliyor veya ek komut yürütmenin önü açılıyor (ayrıntılı analiz için ek inceleme gerekli)
codeowners-validator güvenlik açığı: yerel dosya dahil etme
- İkinci ve daha ciddi açık, CODEOWNERS dosyası doğrulama iş akışında bulundu
- Bu süreç PR kodunu checkout ettikten sonra dosyaları codeowners-validator ile denetliyordu
- PR gönderen kişi, OWNERS dosyasını sembolik bağlantıyla değiştirebilir ve böylece çalıştırıcı üzerindeki keyfi dosyalara başvurabilirdi (örneğin action kimlik bilgileri)
- Sonuç olarak doğrulama sırasında bu dosyanın içeriği loglara yazılıyor ve read/write yetkisine sahip GitHub token'ı açığa çıkıyordu
- Bu token ele geçirildiğinde, Nixpkgs deposuna doğrudan push atmak mümkün hâle geliyordu
Önlemler ve çıkarılan dersler
- Güvenlik açığı bildirildikten sonra, Nixpkgs maintainer'ı infinisil hemen müdahale etti
- Savunmasız iş akışları geçici olarak devre dışı bırakıldı
- Güvenilmeyen veri ile yetkilerin bağlandığı kısımlar düzeltildi ve ayrıştırıldı
- Güvenlik düzeltmesinden sonra branch targeting sorununu hafifletmek için iş akışı adları değiştirildi
- Temel dersler
- Güvenilmeyen veriyi sırlarla ve hassas işlemlerle birleştirmemek, ya da en azından buna azami dikkat göstermek gerekir
- En az ayrıcalık ilkesine uyulmalıdır
- GitHub Actions yetkileriyle ilgili resmî kılavuzları bilmek zorunludur
- Benzer açıklar ortaya çıktığında, kurum yöneticileri politika üzerinden Actions'ı topluca devre dışı bırakabilir (ayar yöntemi de açıklanıyor)
Sonuç
- Araştırmacı bir gün içinde Nix ekosisteminin tamamını riske atabilecek bir açığı buldu, bildirdi ve düzeltilmesine katkı sundu
- Bu olay, GitHub Actions'ta özellikle
pull_request_target kullanılırken çok daha dikkatli olunması gerektiğini gösteriyor
- Araştırmaya yardım eden KITCTF'den Intrigus'a ve hızlı müdahale eden infinisil'e teşekkür ediliyor
- İlgilenen okuyucuların sunum videosuna ve ek materyallere göz atması öneriliyor
- Genel olarak, GitHub Actions güvenliğinin önemi ve pratik dersleri vurgulanıyor
1 yorum
Hacker News görüşü
Bence
pull_request_targettemelden güvenlik açısından kırılgan ve GitHub bu özelliği tamamen kaldırmalı. Geneldepull_request_targetı güvenli kullanmanın, dal tarafından kontrol edilen kodu işlem sırasında çalıştırmamak anlamına geldiği söylenir ama gerçekte argüman enjeksiyonu veya yerel dosya dahil etme gibi sorunlar yüzünden saldırı yüzeyi çok daha geniştir. Şu anda meşru kullanım örnekleri en fazla üçüncü taraf PR’lere otomatik etiket eklemek ya da otomatik yorum yazmak seviyesinde. Böyle işler için depoya varsayılan olarak yazma izni vermek gerekmemeli. GitHub’ın bu tür işler için yalnızca ilgili göreve özel token verebilmesi gerekir. Bu yüzden zizmor’dapull_request_targetgibi tehlikeli tetikleyiciler kullanıldığında hepsini işaretliyorum; bkz. zizmor dangerous triggerspull_requestworkflow’u tetiklenmiyor. Bu durumdapull_request_targetfiilen tek seçenek oluyor. Keşke GitHub, temiz merge edilmeyen PR’lerde workflow çalıştıracak bir ayar sunsa da varsayılanı kapalı olsa ve sadece linter gibi işler için kullanılsa. O zamana kadar bu sınırlama yüzünden mecburenpull_request_targetkullanmak zorunda kalınması gerçekten üzücü. Ayrıca böyle harici araçlar kullanılırken GitHub’da manuel merge yapılırsa tüm akış bozulur; kesinlikle manuel merge yapılmamalıpull_request_targetı iki nedenle kullanıyoruz. Birincisi, workflow her zaman main’e göre çalıştığı için doğrulanmamış test kodlarını engelleyebiliyoruz. İkincisi, workflow içindeki JWT’nin sub claim’indejob_workflow_refbelirleyici biçimde sağlandığından OIDC tabanlı sistemlerde ayrıntılı erişim kontrolü mümkün oluyorpull_request_target, PR’nin base context’inde çalışır; bu da kötü niyetli kodun repo ya da secret’ları çalmasını engellemelidir. Ama gerçekte secret sızdırmanın ne kadar kolay olduğunu görünce durum biraz komik kalıyorNix ekibi, benim önerdiğim RFC doğrultusunda imzalı commit/review’den bağımsız imzalı yeniden üretilebilir build’leri hayata geçirmiş olsaydı, bu tür son aşama tedarik zinciri saldırıları mümkün olmazdı. Sonuçta NixPkgs herkesin kolayca düzenleyebilmesini istiyor ve güvenliğe odaklanan girişimlerin gönüllüleri kaçırmasından çekiniyor; amaç hobi amaçlı bir dağıtıma odaklanmak. Bu kendi başına sorun değil ama bu özelliği insanlara açıkça anlatıp gerçekten değerli olanı korumak istiyorsanız, Nix’i güvenlik açısından kritik ortamlarda kullanmayı ya da önermeyi bırakmalısınız. Bir şeyi koruyan bir OS, her değişiklik için sıkı iki taraflı donanım imzası istemeli ve güveni tek bir makineye ya da tek bir kişiye bırakmamalı. Bu yüzden Stagex’i yaptım Stagex bağlantısı Codeberg bağlantısı
Bilgisayar sistemleri geleneksel olarak böyle tasarlanmış olmasına rağmen, günümüz workflow’larının hâlâ bearer token’lara, hatta kısa ömürlü olanlara bile, bunları güvenilen programlara vermesine çok şaşırıyorum. GitHub Actions çerçevesi bunun yerine sadece ayrıcalıklı Unix socket ya da
ssh-agenterişimi sağlasaydı, bu tür açıkların istismar edilmesi çok daha zor olurduPull/merge istekleri için CI/CD action’ları tam bir kâbus. Geliştiriciler test ya da doğrulama adımlarını yazarken çoğunlukla "benim kodum benim GitHub/GitLab hesabım bağlamında çalışıyor" diye düşünüyor. Bu, kişinin kendisi ya da ekip arkadaşlarının commit’leri için doğru olabilir ama PR’lerde CI/CD pipeline’ı güvenilmeyen kodu çalıştırır. Bu farkı her zaman doğru biçimde akılda tutmak zor. Basit testler veya linter’lar için sorun olmayabilir ama altyapıyla konuşması gereken ve daha fazla yetki isteyen işler eklenince çok hızlı şekilde tehlikeli hâle gelir
pull_requestvepull_request_target. Bunlardan biri (pull_requestgibi) özellikle yanlış kullanmadığınız sürece neredeyse güvenli, diğeri ise (pull_request_targetgibi) neredeyse güvenli kullanılamıyor. Asıl büyük sorun, GitHub’ın PR’ye etiket eklemek veya otomatik yorum bırakmak gibi sıradan işleri bile yalnızca tehlikeli tetikleyici (pull_request_target) altında mümkün kılması; böylece herkes mecburen kırılgan seçeneğe itiliyor. GitHub Actions’ın sunduğu yapı hata yapmayı teşvik ediyorZaman geçtikçe tedarik zinciri saldırıları konusunda giderek daha fazla endişeleniyorum. Mesele sadece "bunun yüzünden işimi kaybeder miyim" ya da "NixOS, CI/CD, Node vb. içinde yeni bir saldırı vektörü mü çıktı" düzeyinde değil; daha felsefi bir kaygı. Bir şeye ne kadar çok bağımlı olursanız, uğraşmanız gereken sorunlar da kaçınılmaz olarak o kadar artıyor. Rahatça kullanmak istediğiniz şeyler bile artık fazlasıyla dolaşık—VSCode, Emacs, Nix, Vim, Firefox, JS, Node ve bunların bütün eklenti ile bağımlılık paketleri birbirine girmiş durumda. Bu yüzden utanarak söylüyorum, giderek kâğıda ve minimum düzeyde, gerçekten basit teknolojiye dönmem gerektiği gibi garip bir sonuca yaklaşıyorum; ancak o zaman kontrol ya da güvenlik hissi elde edebiliyorum. Bunun irrasyonel olduğunu biliyorum ama bu karmaşıklıktan giderek daha çok bıkıyorum. Artık karmaşıklık sınırına geldiğimi bile hissediyorum
xargsman sayfasındaki uyarıda “xargs güvenli şekilde kullanılamaz” denir. Ama bu güvenlik sorunu, burada uygulanan vakayla farklı. Bu olayda sona sadece--eklemek yeterli olurdu“xargs güvenli şekilde kullanılamaz” ifadesi sık sık yanlış anlaşılıyor. Örneğin
cat "$HOME/changed_files" | xargs -r editorconfig-checker --şeklinde çalıştırırsanız burada söz konusu olan spesifik problem çözülebilir<div>{escapeHtml(value)}</div>yazarak XSS engellemeye benziyor. Güvenli kullanımın her yerde elle uygulanması gerekiyorsa, yaklaşımın kendisi baştan yanlıştır--gibi argüman ayırıcısını desteklemez vexargskullanımının çoğu argüman enjeksiyonuna açıktır. Bir bakıma tüm komut çalıştırmalarının özünde riskli olmasına benzer. Bu,xargsın kendi suçu değil; araçların farklı yetki bağlamlarında tekrar tekrar kullanıldığı gerçek dünyadan kaynaklanan bir sorunYazıda çok daha geniş etki alanına sahip ölümcül bir açık daha var: PR kodunda OWNERS dosyasını symlink’e çevirip GitHub Actions kimlik bilgisi dosyası gibi rastgele dosyaları açığa çıkarabilirsiniz. Git, softlink commit’lerini desteklediği için neredeyse her workflow’da bu risk ortaya çıkıyor
pull_request_targetçalıştırıldığında kimlik bilgileri hedef repo, yani merge edilecek repo bağlamında olur.pull_requestaltında çalıştırırsanız kimlik bilgileri saldırganın kontrol ettiği kaynak repo bağlamında olurTek “iyi” haber şu olabilir: OpenBSD ve NetBSD hâlâ paket yönetiminde CVS kullandığı için bu açıktan etkilenmiyor. FreeBSD’den emin değilim. Güvenlik bazen gizlenme etkisi yaratıyor. Gerçi o projelerin de Git’e geçmeyi düşündüğü anlaşılıyor; OpenBSD muhtemelen got(1) tabanlı bir yola gidecek