Genel Bakış
Serializasyon, bellekteki bir nesneyi depolanabilir ya da iletilebilir hale getirmek için bayt akışına veya yapılandırılmış metne dönüştürme işlemidir. Deserializasyon ise bunun tersidir: bir nesneyi bu gösterimden yeniden oluşturmak. Güvensiz deserializasyon; bir uygulama, saldırgan tarafından sağlanan ya da etkilenen verileri bütünlüğünü doğrulamadan veya izin verilen nesne türlerini kısıtlamadan deserialize ettiğinde ortaya çıkar.
Deserializasyon işlemi nesne yeniden oluşturma sırasında yapıcı çağrılarını, özellik ayarlayıcılarını ve sihirli metodları tetikleyebildiğinden, serileştirilmiş yükü kontrol eden bir saldırgan çoğunlukla uygulamanın hedeflediğinin çok ötesine geçen sonuçlar elde edebilir — en ağır senaryoda sunucu üzerinde uzaktan kod yürütme (RCE).
Nasıl Çalışır?
Saldırı yüzeyi büyük ölçüde çalışma ortamına ve serializasyon formatına bağlıdır; ancak genel mekanizma tutarlıdır:
- Saldırgan kontrolündeki serileştirilmiş veri uygulamaya girer — çerezler, POST gövdesi, HTTP başlıkları, API yükleri, mesaj kuyrukları veya paylaşılan önbellekler aracılığıyla.
- Uygulama doğrulama yapmadan deserialize eder — kriptografik imzayı kontrol etmeden, izin verilen sınıfları kısıtlamadan veya alan değerlerini temizlemeden nesneleri yeniden oluşturur.
- Araç zincirleri (gadget chain) tetiklenir — saldırgan, nesne grafiği JVM/CLR/yorumlayıcıda hâlihazırda yüklü olan ve bir arada saldırgan tarafından sağlanan komutları yürüten sınıflardan geçen bir yük oluşturur. ysoserial (Java), phpggc (PHP) ve pwnlib (Python) gibi araçlar araç zinciri keşfini ve yük oluşturmayı otomatikleştirir.
- Etki gerçekleşir — mevcut araç zincirine bağlı olarak RCE, rastgele dosya okuma/yazma, SSRF, hizmet engeli veya kimlik doğrulama atlatma söz konusu olabilir.
Dile özgü notlar:
- Java:
ObjectInputStream.readObject()klasik giriş noktasıdır. Yaygın kütüphanelerde (Apache Commons Collections, Spring Framework vb.) onlarca araç zinciri mevcuttur. - PHP:
unserialize(), saldırgan kontrolündeki sınıflar üzerinde__wakeup(),__destruct()ve__toString()sihirli metodlarını tetikler. - Python:
pickle.loads(), yalnızca bir uygulama hatası değil tasarım düzeyinde bir risk olan__reduce__protokolü aracılığıyla rastgele Python kodu yürütür. - .NET:
BinaryFormatter,NetDataContractSerializerve tür adı çözümlemesi etkin Newtonsoft.Json'dakiTypeNameHandlingbilinen saldırı yüzeyleridir; Microsoft,BinaryFormatter'ı .NET 5+ sürümlerinde kullanımdan kaldırmıştır. - YAML/XML: Tür etiketlerini çözümleyen ayrıştırıcılar (PyYAML
yaml.load(), XStream) rastgele sınıfları örnekleyebilir.
İş Etkisi
Başarılı bir sömürü, sunucunun tamamen ele geçirilmesine yol açabilir. Somut sonuçlar şunlardır:
- Uzaktan kod yürütme: Saldırganlar işletim sistemi düzeyinde erişim kazanarak veri sızdırma, fidye yazılımı dağıtma veya sunucuyu bir pivot noktası olarak kullanabilir.
- Kimlik doğrulama ve yetkilendirme atlatma: Değiştirilmiş oturum nesneleri veya rol alanları, geçerli kimlik bilgileri olmaksızın yönetici ayrıcalıkları tanıyabilir.
- Veri bütünlüğü ihlali: Saldırganlar, iş nesnelerini (fiyatlar, miktarlar, kullanıcı kimlikleri gibi) kalıcı hale getirilmeden önce değiştirebilir.
- Hizmet engeli: Derin iç içe geçmiş veya döngüsel nesne grafikleri, yeniden oluşturma sırasında bellek veya CPU tükenmesine neden olabilir.
- Yasal yükümlülük: Sunucu ele geçirilmesi genellikle GDPR, HIPAA, PCI DSS ve benzeri düzenlemeler kapsamında ihlal bildirim yükümlülüklerini, ilgili para cezalarını ve itibar zararını beraberinde getirir.
Nasıl Düzeltilir?
- Güvenilmeyen verileri deserialize etmekten tamamen kaçının — rastgele nesneler örnekleyemeyen yalnızca veri formatlarını (tür ipuçları içermeyen düz JSON, Protocol Buffers, MessagePack) tercih edin.
- Bütünlük doğrulaması uygulayın — serileştirilmiş yükleri HMAC veya dijital imzayla imzalayın ve deserializasyondan önce imzayı doğrulayın. İmzası eşleşmeyen yükleri reddedin.
- Deserialize edilebilir türler için katı izin listesi uygulayın — Java'da
ObjectInputStream'i, açık bir beyaz listede bulunmayan sınıfları reddeden özel birresolveClass()ile sarın (örn. Apache Commons IO'nunValidatingObjectInputStream'i veya JEP 290 seri filtre mekanizması). .NET'te Newtonsoft.Json'daTypeNameHandling.Nonekullanın veBinaryFormatter'dan kaçının. - Kullanımdan kaldırılmış serileştiricileri yükseltin veya değiştirin — .NET'te
BinaryFormatter'dan, güvenilmeyen veriler için Python'dapickle'dan ve güvenli yükleyici kullanmadanyaml.load()'dan (yaml.safe_load()kullanın) uzaklaşın. - Deserializasyonu korumalı bir bağlamda çalıştırın — başarılı bir saldırının etkisini sınırlamak için deserialize eden süreci düşük yetkili bir hesap, konteyner veya işletim sistemi düzeyinde korumalı alan (seccomp, AppArmor) içinde izole edin.
- Bağımlılıkları güncel tutun — araç zincirleri çoğunlukla üçüncü taraf kütüphanelerin zafiyetli sürümlerine dayanır. SCA araçlarını kullanarak bağımlılıkları düzenli olarak denetleyin ve güncelleyin.
- Deserializasyon olaylarını kaydedin ve izleyin — aktif tarama girişiminin göstergesi olabilecek beklenmedik sınıf örneklemesi, olağandışı büyük yükler veya deserializasyon hatalarında uyarı oluşturun.
- Güvenlik testi yapın — penetrasyon testlerine deserializasyon saldırı yüklerini dahil edin ve maruziyeti doğrulamak için kontrollü ortamlarda ysoserial veya phpggc gibi araçları kullanın. Sensagraph, web uygulamalarındaki güvensiz deserializasyon göstergelerini otomatik olarak tespit eder.
Referanslar
- OWASP Top 10 A08:2021 – Yazılım ve Veri Bütünlüğü Hataları
- OWASP Deserializasyon Kopya Kağıdı
- MITRE CWE-502: Güvenilmeyen Verinin Deserializasyonu
- JEP 290: Gelen Serializasyon Verisinin Filtrelenmesi (OpenJDK)
- Microsoft: BinaryFormatter Güvenlik Kılavuzu
- Python Belgeleri: pickle – Genel Değişkenlerin Kısıtlanması
- ysoserial – Java Deserializasyon Yük Oluşturucu (GitHub)
- PortSwigger Web Güvenlik Akademisi: Güvensiz Deserializasyon