Yeni bir araştırma, imzalı bir Git commit'inin hash'inin, yazılım dünyasının varsaydığı gibi benzersiz bir kimlik olmadığını ortaya koyuyor. Carnegie Mellon Üniversitesi'nde doktora öğrencisi ve Cure53'te kriptografik denetçi olan Jacob Ginesin tarafından yapılan çalışmaya göre, herhangi bir imzalı commit için, imzalama anahtarına sahip olmayan bir kişi, aynı dosyalara, yazara ve tarihe sahip ikinci bir commit oluşturabiliyor ve bu commit geçerli bir imzayla GitHub'da 'Verified' (Doğrulanmış) olarak işaretleniyor. Bu durum, commit hash'ine güvenen birçok sistemi etkiliyor.
Güvenlik açığı, imza değiştirilebilirliğinden (signature malleability) kaynaklanıyor. Bir commit'in hash'i, içindeki her şeyin üzerinden hesaplanıyor; buna başlığındaki imzanın ham baytları da dahil. Birçok imza, farklı ama yine de geçerli bir forma dönüştürülebiliyor ve bu baytları değiştirmek, tek bir kod satırına dokunmadan hash'i değiştiriyor. Ginesin'in geliştirdiği araç, GitHub'ın doğruladığı tüm GPG şemalarını ve S/MIME'i kapsayan üç farklı saldırı yöntemi kullanıyor: ECDSA anahtarlarında s değerini n-s'ye çevirerek, RSA ve EdDSA anahtarlarında imzanın 'karma olmayan' bölümüne ek bir alan ekleyerek ve S/MIME (X.509) anahtarlarında DER yapısındaki bir uzunluk alanını değiştirerek.
Bu saldırıların ortak noktası, GitHub'ın imzayı kontrol etmeden önce normalleştirmemesi. S/MIME için katı bir kodlama yok, OpenPGP alanları temizlenmiyor ve kanonik olmayan ECDSA değerleri olduğu gibi kabul ediliyor. GitHub daha sonra her commit hash'ine karşı bir 'Verified' kaydı oluşturuyor ve bu kaydı yeniden kontrol etmiyor. Bu nedenle, imzalama anahtarı iptal edildikten sonra bile bir commit 'Verified' olarak kalıyor. Orijinal commit ve onun ikizi iki farklı dala itildiğinde, GitHub'ın karşılaştırma görünümü, aynı dosyalara rağmen onları farklı geçmişler olarak ele alıyor.
Sistem Güvenliği
Bu güvenlik açığı, bir hash çarpışması değil. SHA-1 veya SHA-256'yı kırmıyor ve iki farklı commit'in aynı hash'i paylaşmasıyla ilgili değil. Tam tersine, bir commit'in birçok geçerli yolla yazılabildiği ve her birinin kendi hash'ine sahip olduğu bir durum söz konusu. Bitcoin yıllar önce aynı ECDSA simetrisiyle mücadele etmişti; çözüm, yalnızca 'düşük-S' formunu kabul etmekti. Ginesin'in makalesi de benzer bir çözüm öneriyor: hash'e güvenmeden önce kodlamayı kanonikleştirin.
Detaylar ve Etkileri
Makale ayrıca bu açığı yakın zamandaki GitHub Actions etiket gaspı saldırılarıyla (tj-actions/changed-files ve trivy-action) ilişkilendiriyor. Bu saldırılardan sonra verilen tavsiye, hareketli bir etiket yerine tam bir commit hash'ine sabitlemekti. Bu tavsiye hâlâ geçerli; çünkü sabitlenmiş bir hash, doğru kodu getirmeye devam ediyor. Ancak bu araştırma, doğrulanmış bir commit hash'ine aşırı güvenmemek gerektiğini gösteriyor. Geçerli bir imza, commit'i kimin imzaladığını kanıtlıyor ancak hash'in içerdiği şey için benzersiz bir isim olduğunu garanti etmiyor.
Peki kim harekete geçmeli? Geliştiriciler değil; çünkü sabitlenmiş bir hash hâlâ doğru kodu getiriyor. Asıl iş, forklar (GitHub gibi platformlar) için. Makale, forkların imzaları kanonikleştirmesi gerektiğini söylüyor. Commit hash'ine göre bloklama, kopya temizleme veya kaynak doğrulama yapan araçlar da aynı şeyi yapmalı: ham hash'e güvenmek yerine önce doğrulama ve kanonikleştirme yapmalı. Nix'in sabit çıktılı türevleri gibi, getirilen dosyaların bağımsız bir hash'ini de sabitleyen sistemler bu açıktan daha az etkileniyor.
Ginesin, sorunu Ocak ayında GNU ve Git'e, Mart ayında ise GitHub'a bildirdiğini söylüyor. Makalenin 2 Temmuz'da arXiv'de yayımlanmasıyla birlikte, üç saldırıyı da çalıştıran herkese açık bir araç ve değiştirilmiş commit'lerin GitHub'da hâlâ 'Verified' gösterildiği iki demo deposu da paylaşıldı. Bu araştırma, yazılım tedarik zinciri güvenliğinde yeni bir farkındalık yaratırken, forkların ve güvenlik araçlarının imza doğrulama süreçlerini gözden geçirmesi gerektiğini ortaya koyuyor.
Kaynak: thehackernews.com