CodeQL tedarik zinciri saldırısı tehdidi – Açığa çıkan GitHub gizli anahtarından başlayan güvenlik olayı
(praetorian.com)- Kısa süreli geçerli olan açık bir GITHUB_TOKEN, CodeQL kullanan birçok deponun GitHub Actions workflow’larında kod çalıştırmaya uzanan bir tedarik zinciri saldırısı yolunu mümkün kılabilirdi
- Token,
github/codeql-actiondeposundaki başarısız bir debug workflow’un yüklediği workflow artifact içinde yer alıyordu vecontents: write,actions: write,packages: writeizinlerine sahip bir GitHub App kurulum token’ıydı - Saldırının başarıya ulaşması, artifact yüklendikten iş tamamlanana kadar geçen sürede token’ın indirilip kullanılmasına bağlı olan bir race condition durumuna dayanıyordu; gerçek loglara göre yaklaşık 1.022 saniye, gözleme göre yaklaşık 2 saniye içinde branch oluşturma,
poc.txtpush etme ve tag oluşturma başarıyla yapıldı - Varsayılan CodeQL yapılandırması dahili olarak
github/codeql-actiondeposunun v3 tag’ini çalıştırıyordu ve bu tag değiştirilemez değildi; bu nedenle saldırgan tag’i kötü amaçlı bir commit’e taşısa, varsayılan CodeQL workflow’unu kullanan depolar da etkilenebilirdi - GitHub, bildirimden yaklaşık 3 saat sonra debug artifact yüklemelerini devre dışı bırakan bir PR açtı, CVE-2025-24362 atadı ve advisory’de platform ya da sistem ihlaline dair kanıt bulunmadığını belirtti
Açık artifact ile başlayan CodeQL tedarik zinciri saldırı yolu
- Açığa çıkan tek bir secret, GitHub CodeQL’e yönelik potansiyel bir tedarik zinciri saldırısına dönüşebilirdi
- Bu secret bir seferde yalnızca yaklaşık 1.022 saniye geçerliydi, ancak bu süre içinde saldırganın GitHub Actions workflow içinde kod çalıştırmaya giden adımları yerine getirmesi mümkündü
- Etki alanı hem GitHub Cloud hem de GitHub Enterprise’a uzanabilirdi
- Olası zararlar şunlardı
- CodeQL kullanan private depoların kaynak kodunun sızdırılması
- CodeQL workflow job’ları içindeki GitHub Actions secrets bilgilerinin ele geçirilmesi
- CodeQL workflow’larının çalıştığı iç altyapıda kod çalıştırılması
- CodeQL kullanan depolarda GitHub Actions Cache kullanan workflow’ların secrets bilgilerinin ele geçirilmesi
- GitHub advisory’sine göre GitHub, platform veya sistem ihlaline dair bir kanıt bulmadı
Secret’ın nasıl bulunduğu
- GitHub Actions workflow artifact’lerini indirip arşivleri özyineli olarak açtıktan sonra Nosey Parker ile secret taraması yapan bir Actions Artifacts Secret Scanner kullanıldı
- Bu özellik Chariot’a entegre edildi ve Gato özelliği olarak açık kaynak hâline getirildi
- Bir gün boyunca yapılan taramanın ardından
github/codeql-actiondeposunun artifact’lerinde token bulundu- Hedef artifact, “PR Check – Debug artifacts after failure” workflow’unun yüklediği
my-debug-artifactszip dosyasıydı - İçindeki
my-db-java-partial.zipaçıldığında, crash report içindeghs_ile başlayan bir GitHub Token tespit edildi - Manuel inceleme sonucunda bunun, GitHub Runner ortam değişkenlerini içeren bir dosyada saklanan GitHub App kurulum token’ı olduğu anlaşıldı
- Hedef artifact, “PR Check – Debug artifacts after failure” workflow’unun yüklediği
GitHub Actions, artifact ve CodeQL arasındaki bağlantı yapısı
- GitHub Actions, YAML workflow’larında tanımlanan işleri runner üzerinde çalıştıran bir CI/CD platformudur
- Her workflow çalıştırması, otomatik olarak oluşturulan bir GitHub App kurulum token’ı olan GITHUB_TOKEN üretir
- Runner, workflow’un gerektirdiği işleri yapmak için bu token ile GitHub’a kimlik doğrular
- İzinler workflow dosyası, depo ve organizasyon düzeyinde ayarlanabilir
- GitHub Actions workflow artifact’i, workflow’un daha sonra kullanmak üzere GitHub Actions’a kaydettiği dosyalardır
- Varsayılan olarak depoda okuma yetkisi olan herkes erişebilir
- En fazla 90 gün boyunca saklanır
- CodeQL, GitHub’un kod analiz motorudur ve GitHub depolarında statik analiz yaparak zafiyetleri bulmak için kullanılır
- CodeQL gibi güvenlik araçları hassas sistemlere ve verilere erişmek zorunda kalabildiğinden, ele geçirilirlerse bir arka kapı hâline gelebilirler
Token izinleri ve race condition
- Workflow loglarındaki “Setup Job” adımı, ilgili GITHUB_TOKEN’ın tam yazma iznine sahip olduğunu gösterdi
- Özellikle kritik izinler şunlardı
contents: write: branch oluşturma, tag oluşturma, release artifact yüklemeactions: write: Actions işleri veworkflow_dispatchevent’ini tetiklemepackages: write: package yükleme
- Token yalnızca ilgili workflow job’ı çalıştığı sürece geçerli olduğundan, saldırı için üç koşul gerekliydi
- Token’ın yazma iznine sahip olması
- Job tamamlanmadan önce artifact alınmasına izin veren upload artifact API v4’ün kullanılması
- Artifact yükleme ile job tamamlanması arasındaki sürenin token’ı indirme, arşivi açma ve kullanma için yeterli olması
- CodeQL,
actions/upload-artifactaction’ını doğrudan kullanmıyor; bunun yerine kaynak kod içinden upload artifact istemcisini manuel olarak kullanıyordu ve kod yorumlarına göre version 4 kullanılıyordu - Ham GitHub loglarına göre zaman aralığı çok kısaydı
- “Finalizing artifact upload”: 17:22:09.888
- “Cleaning up orphan processes”: 17:22:10.911
- Hesaplamaya göre yaklaşık 1.022 saniyeydi; gözleme göre cleanup sonrasında token yaklaşık 1 saniye daha geçerli kaldığından toplam yaklaşık 2 saniye kabul edildi
PoC: artifact_racer.py çalıştırılması
- Doğrulama için
artifact_racer.pyadlı bir Python script’i yazıldı - Çalışma akışı şöyleydi
github/codeql-actiondeposunda “PR Check – Debug artifacts after failure” workflow’unun başlayıp başlamadığı sürekli sorgulanıyor- Çalışmakta olan workflow’un artifact’leri izleniyor
- Artifact görünür görünmez indiriliyor ve GITHUB_TOKEN çıkarılıyor
- Çıkarılan token ile yeni bir branch oluşturuluyor
- Bu branch’e
poc.txtadlı boş bir dosya push ediliyor - İlgili commit için yeni bir tag oluşturuluyor
- Artifact boyutu yaklaşık 21MB olduğundan, süre içinde başarılı olmanın mümkün olduğu düşünüldü
- Test deposunda başarı sağlandıktan sonra işlem
github/codeql-actiondeposuna karşı çalıştırıldı - Yaklaşık 2 saat sonra workflow çalıştı ve script token’ı alarak branch oluşturma, dosya push etme ve tag oluşturma işlemlerini başarıyla tamamladı
Tag manipülasyonunun etki alanını büyütmesi
- Saldırgan, bu token ile korunmayan bir branch’e kötü amaçlı kod ekleyebilirdi
- Daha gizli bir yöntem olarak, merge öncesi bir feature branch’e küçük kötü amaçlı değişiklikler koyup merge’ü beklemek de mümkündü
- Tag oluşturma izni de kritikti
- Kötü amaçlı kod içeren commit’e
v3tag’i eklenirse,codeql-action@v3ü manuel kullanan kullanıcılar kötü amaçlı kodu çalıştırabilirdi
- Kötü amaçlı kod içeren commit’e
- Daha büyük etki, varsayılan CodeQL yapılandırmasından kaynaklanıyordu
- Depo ayarlarından CodeQL varsayılan yapılandırmayla etkinleştirildiğinde, depo workflow listesinde görünmeyen özel bir GitHub Actions workflow’u çalışır
- Bu workflow depo checkout, CodeQL başlatma, CodeQL taraması ve sonuç yükleme işlemlerini yapar
- Dahili olarak
github/codeql-actiondeposundaki action’ı, v3 tag’inin işaret ettiği commit üzerinden çalıştırır
- O sırada
v3tag’i değiştirilemez değildi ve GitHub’un önerdiği workflow pinning de kullanılmıyordu - Saldırgan, ele geçirilmiş GITHUB_TOKEN ile
v3tag’ini kötü amaçlı bir commit’e taşıyabilirse, varsayılan CodeQL workflow’unu kullanan depolar kötü amaçlı CodeQL action’ını çalıştırabilirdi - CodeQL action’ı çalıştığı depodaki kaynak kodu checkout ettiği için, kötü amaçlı action varsayılan CodeQL yapılandırmasını kullanan depoların kaynak kodunu dışarı sızdırabilirdi
GitHub Actions Cache poisoning yolu
- Varsayılan CodeQL action’ının GITHUB_TOKEN’ı yalnızca okuma iznine sahip olduğundan, sadece varsayılan yapılandırma ile doğrudan depo yazma işlemleri, release arka kapısı ya da
workflow_dispatchüzerinden secrets ele geçirme mümkün değildi - Bunun yerine varsayılan CodeQL action’ı deponun main branch’inde çalışır
- GitHub depolarında main branch, depo genelinde kullanılabilecek cache entry’leri yazabildiği için GitHub Actions cache poisoning fırsatı doğar
- GitHub Actions Cache Poisoning, Adnan Khan’ın yazısında ele alınan bir tekniktir; Cacheract ise cache poisoning ile build pipeline içinde kalıcılık bırakan bir malware’dir
- Saldırgan CodeQL workflow içinde Cacheract’i dağıtırsa şu akış mümkün olabilirdi
- Cache entry’yi tahmin etme
- İlgili entry’yi kötü amaçlı action ile ezme
actions/cachekullanan workflow’da kod çalıştırma elde etme- Bu workflow’un GitHub Actions secrets bilgilerini ve daha yüksek yetkili GITHUB_TOKEN’ını ele geçirme
- Kötü amaçlı CodeQL action’ı tespit edilip zafiyet giderilse bile, Cacheract cache poisoning yapmaya devam edebilirdi
- Hem CodeQL hem de
actions/cachekullanan önemli repo örnekleri arasında Homebrew, Angular, Grafana yer alıyor
CVE-2025-24362 ve düzeltme
- Bu açıklama sonucunda CVE-2025-24362 atandı
- Açığa çıkan GITHUB_TOKEN, başarısız bir code scanning workflow’undan sonra CodeQL Action’ın yüklediği debug artifact içinde yer alıyordu
- CodeQL Actions deposu kasıtlı olarak hataya düşürülüyordu, ancak diğer CodeQL Actions kullanıcılarında da benzer bir hata oluştuysa kendi secret’larını workflow ortam değişkenleri yoluyla açığa çıkarmış olabilirlerdi
- Bu sorun CodeQL Action 3.28.3 sürümünde giderildi
- En büyük potansiyel etki, CVE’nin kendisinden çok, CodeQL Actions deposunun istismar edilip CodeQL kullanıcılarına karşı bir tedarik zinciri saldırısı yürütülebilmesi yolunda yatıyordu
GitHub’un yanıtı ve önerilen önlemler
- GitHub’un müdahale takvimi şöyleydi
- 22 Ocak 2025 15:13 UTC: GitHub’a bildirim gönderildi
- 22 Ocak 2025 17:48 UTC: GitHub alındıyı doğruladı
- 22 Ocak 2025 18:28 UTC: GitHub zafiyeti doğruladı, “PR Check – Debug artifacts after failure” workflow’unu geçici olarak devre dışı bıraktı ve debug artifact yüklemelerini devre dışı bırakan bir PR gönderdi
- 24 Ocak 2025: GitHub, CVE-2025-24362 atadı ve security advisory yayımladı
- GitHub Actions workflow artifact’lerinde secret açığa çıkma riskini azaltmak için şu önlemler öneriliyor
- Workflow artifact olarak yalnızca belirli dosya veya dizinleri yüklemek
- Ortam değişkenlerini,
.git/configdosyasını ve runner’ın<path_to_runner_dir>/_work/_temp/dizinindeki dosyaları içeren artifact yüklemelerinden kaçınmak - GITHUB_TOKEN izinlerini salt okunur olacak şekilde sınırlamak
- Artifact yüklemeden önce secret taraması yapmak
1 yorum
Hacker News yorumları
GitHub immutable actions özelliğini daha hızlı zorlasaydı bunun etkisi çok daha sınırlı olurdu.
Bu özelliğin şu anda GitHub Actions saldırı yüzeyinin %70’inden fazlasını engelleyeceğini tekrar tekrar söylemek zorunda kalıyorum. Her hafta bir olay yaşandığını görünce artık yayımlanma zamanı geldi diye düşünüyorum.
[1] https://github.com/features/preview/immutable-actions
Bu geçici tokenın neden yeni dağıtım oluşturma ve artifact attestations üretme yetkisine kadar sahip olduğuna dair bir açıklama yok.
Düzeltme olarak debug loglarının kapatıldığını söylediler ama geçici token izinlerinin kod analiz motoruna daha uygun şekilde değiştirilip değiştirilmediğine yanıt vermediler.
Geçmişte varsayılan yalnızca izin verici ayardı; bu yüzden eski organizasyon ve depolarda ne yazık ki bu ayar sıkça kullanılıyor.
Yeni bir depo oluşturduğunuzda üst organizasyonun varsayılanını devralır; biri değiştirmezse bu güvensiz varsayılan kalmaya devam eder. Kullanıcı geneli için bir ayar yok, bu yüzden kişisel sahipli yeni depolar kısıtlayıcı varsayılanı kullanır. Yeni oluşturulan organizasyonların da daha iyi varsayılanı kullandığını biliyorum.
[0]: https://docs.github.com/en/actions/security-for-github-actio...
CI ve CD’nin tamamen ayrı ortamlar olması gerektiğine giderek daha çok ikna oluyorum. CI ele geçirildi diye CD ile ilgili token’ların sızmaması gerekir.
Örneğin
"sub":"repo:octo-org/octo-repo:environment:prod"[1] gibi bir koşulun mutlaka sağlanmasını zorunlu kılabilir, sistemi daha sağlam yapmak isterseniz başka [fun claims][] de ekleyebilirsiniz.1: https://docs.github.com/en/actions/security-for-github-actio...
fun claims: https://github.com/github/actions-oidc-debugger#readme
Müdahale süresi şaka değildi. GitHub’ın tepkisi epey etkileyici.
Soyadı Prater olan biri olarak, bu adın Praetorian’dan gelmesi nedeniyle praetorian.com’a sahip olmayı gerçekten isterdim.
Herkese açık GitHub Actions kullanmak sorun davet etmektir; workflow süreçlerini analiz etmiyorsanız daha da öyle.
Bunun yerine woodpecker veya diğer iyi CI builder’ları (circle, travis, gitlab vb.) kendiniz host etmeniz daha iyi.
OpenZFS PR’lerine CodeQL uygulamıştık. Bu OpenZFS için sorun değil. Çünkü kodumuz gizli değil :)
Yine de en azından hızlıca çözülmüş olması iyi.
Bu düzeltildi mi?
Bu sitenin performansı o kadar kötü ki neredeyse kaydırma bile yapamıyorum.