- Konu sahibi
- #1
Risk, güvensiz ters serileştirmede oluşur
Bu başlıkta kastedilen risk, güvensiz ters serileştirmedir (deserialization): uygulamanın dışarıdan gelen serileştirilmiş veriyi yeterince denetlemeden nesneye dönüştürmesi. Saldırgan bu veriyi değiştirerek uygulamanın yetkili işlemler yapmasına, hassas bilgileri okumasına, dosya veya ağ işlemleri başlatmasına ve uygun koşullarda sunucuda kod çalıştırmasına yol açabilir. Risk, verinin yalnızca çerezde veya POST gövdesinde bulunmasından değil, uygulamanın onu güvenilir nesne gibi işleme almasından doğar.
Serileştirme, bir nesneyi saklanabilir veya taşınabilir biçime çevirir; ters işlemde bu veri yeniden nesneye dönüştürülür. Dile ve serileştiriciye göre nesne kurma kancaları, sihirli metotlar veya bağlı kütüphanelerin davranış zincirleri çalışabilir. PHP’de nesne yeniden oluşturulduğunda varsa __unserialize() veya __wakeup() çağrılabilir; bu, normal __construct() çağrısıyla aynı işlem değildir. Saldırganın kendi sınıfını göndermesi her zaman gerekmez; uygulamada zaten bulunan sınıfların beklenmeyen biçimde bir araya gelmesi yeterli olabilir.
Somut varsayımsal örnek
Bir PHP uygulaması oturum bilgilerini çerezde serileştirilmiş biçimde tutuyor ve her istekte bu çerezi doğrudan
unserialize() ile açıyor. Saldırgan çerezi değiştirip normal kullanıcı nesnesi yerine uygulamanın dosya silme veya komut çalıştırma davranışını tetikleyebilecek özellikler içeren bir nesne yapısı gönderiyor.Bu durumda olası sonuç yalnızca çerezin bozulması değildir. Uygulamanın kullandığı kütüphaneler ve sınıflar uygun bir davranış zinciri oluşturuyorsa sunucuda yetkisiz işlem yapılabilir. Zincir yoksa bile rol, kullanıcı kimliği, ödeme durumu veya iş akışı alanlarının değiştirilmesi yetki atlamasına neden olabilir. Hatalı veya aşırı büyük veri ise bellek tüketimi, uzun işlem süresi ya da uygulamanın kullanılamamasıyla sonuçlanabilir.
Başlıca riskler
Aşağıdaki sonuçların gerçekleşip gerçekleşmeyeceği kullanılan dil, kütüphaneler, sınıflar, uygulama yetkileri ve serileştirilmiş verinin ulaştığı noktaya bağlıdır:
| Risk | Nasıl ortaya çıkar? | Olası sonuç |
|---|---|---|
| Kod çalıştırma | Nesne grafiği tehlikeli bir davranış zincirini tetikler | Uygulama yetkileriyle komut veya kod çalışması |
| Yetki atlama | Rol, kullanıcı veya durum alanları değiştirilir | Başka kullanıcıya erişim veya yönetici işlevlerine ulaşma |
| Veri ve dosya işlemleri | Dosya, günlük, ağ istemcisi veya veritabanı davranışları tetiklenir | Veri sızması, değişiklik veya silinme |
| Hizmet dışı bırakma | Aşırı büyük, döngüsel veya maliyetli nesne işlenir | CPU, bellek veya istek kuyruğu tükenmesi |
Şifreleme bu sorunu tek başına çözmez; şifre çözüldükten sonra veri yine güvensiz biçimde nesneye dönüştürülüyorsa saldırı yüzeyi korunur. Base64 gibi kodlamalar da güvenlik kontrolü değildir. Verinin imzalanması ise yalnızca bütünlük doğrulaması ters serileştirmeden önce yapılıyorsa anlamlıdır; doğrulama sonrasında bile içerik güvenli bir biçimde ayrıştırılmalıdır.
Uygulanabilir kontrol ve düzeltme adımları
- Kodda dış girdinin nesneye dönüştürüldüğü yerleri bulun. PHP'de
unserialize(), Java'da nesne akışları, Python'dapickleve benzeri genel amaçlı çözümler öncelikli inceleme noktalarıdır. Çerez, oturum deposu, kuyruk, önbellek, API gövdesi ve gizli alanları da kontrol edin. - Güvenilmeyen veriyi doğrudan nesne olarak yeniden oluşturmayı bırakın. İhtiyaç duyulan alanları açıkça tanımlanmış JSON gibi veri biçimlerinden alın ve tür, uzunluk, aralık, izin verilen değer ve ilişki kontrollerini uygulayın.
- Eski veriyle uyumlulukta dilin güvenlik sınırını kontrol edin. PHP’de allowed_classes kullanmak, güvenilmeyen girdiyi unserialize() ile açmayı güvenli yapmaz; PHP belgesi bunu açıkça önermez. Güvenilmeyen akışı şemalı veri biçimine taşıyın. Güvenilir eski kaynağın geçişini ayrı, sınırlı yetkili bir dönüştürme işi olarak planlayın.
- Veri bütünlüğü gerekiyorsa imzayı veya MAC'i doğrulamadan veriyi ayrıştırmayın. Anahtarı istemciye vermeyin ve bütünlük kontrolünü yetkilendirme kontrolünün yerine koymayın.
- Uygulama hesabının dosya, işletim sistemi komutu, ağ ve veritabanı yetkilerini gereksiz ölçüde geniş bırakmayın. Bu önlem açığı yok etmez; olası etkinin kapsamını azaltır.
- Düzeltmeden sonra normal oturum, geçersiz tür, eksik alan, aşırı uzun alan, bozuk veri ve yetkisiz rol senaryolarını test edin. Günlüklerde ayrıştırma hatalarını, beklenmeyen sınıf adlarını ve olağandışı istekleri izleyin.
Bir giriş noktasında saldırgan kontrollü veri bulunuyorsa, yalnızca ilgili sınıfı engellemek yerine veri akışını güvenli ayrıştırma yöntemine taşımak daha kalıcı çözümdür. Kütüphane güncellemesi yararlı olabilir ancak uygulamanın tehlikeli serileştirme yöntemini kullanmaya devam etmesi halinde tek başına yeterli kabul edilmemelidir.
Sık yapılan hatalar
“Veri çerezde, sunucuda değil” demek: Çerezden gelen veri sunucuda işleniyorsa sunucu tarafındaki kod yine etkilenebilir.
Yalnızca kullanıcı girişini doğrulamak: Kimlik doğrulama, gönderilen nesnenin güvenli olduğu anlamına gelmez. Yetkili bir kullanıcının hesabı ele geçirilmiş veya kötüye kullanılmış olabilir.
Hata mesajını gizlemeyi düzeltme sanmak: Hatanın kullanıcıya gösterilmemesi bilgi sızıntısını azaltır; tehlikeli ayrıştırmayı ortadan kaldırmaz.
Sadece sınıf adlarını filtrelemek: Tehlikeli davranış, izin verilen sınıfların beklenmeyen özellik kombinasyonlarından da doğabilir. Şema tabanlı ve açık alan listeli ayrıştırma tercih edilmelidir.