Uygulama Güvenliği
Mass Assignment Zafiyeti ve Uygulamaları
Mass Assignment (toplu atama) zafiyeti, en derindeki nedenine bakıldığı zaman çok basit bir mantık hatasının kötüye kullanımı ile ortaya çıkan bir zafiyet olduğu görülüyor. Temelinde yatan neden basit olsa da anlaşılması nispeten zor sömürmesi kolay bir zafiyettir, sebepleri yazımızın devamında.
Öncelikle zafiyet isminden de anlaşılacağı üzere toplu olarak veri atanması ile oluşuyor. Zafiyeti anlayabilmek için öncelikle API ara yüzlerinde karşımıza çıkan bir ihtiyacı inceleyelim. Backend kodumuzda bir kullanıcı nesnesi olduğunu düşünelim ve bu kullanıcı nesnesinin modeli aşağıdaki gibi olsun.
Kullanıcıdan alınan bilgileri alıp, kullanıcı modelini oluşturan controller yapımızda tüm bu parametreleri elle mi ayarlayacağız? Çok yönetilebilir bir süreç değil gibi, aynı zamanda modelin değişip daha fazla öznitelik eklenmesi gibi durumlarda geliştirme eforu çıkartabilir. Bunun yerine çoğunlukla API uç noktasına gelirken kullanıcıdan alınan tüm verilerin arka taraftaki UserModel sınıfına eşleştirilmesi çok daha kolay yönetilebilir duruyor.
Son durumda backend ortamımızda birçok öznitelik barındıran bir UserModel sınıfımız ve doğrudan API uç noktasına gelen veriyi UserModel sınıfı ile eşleştiren bir controller yapımız var.
API uç noktasına aşağıdaki gibi bir form girdisinden parse edilen verilerin gönderildiğini düşünelim.
Form girdisinden parse edilen API isteği aşağıdaki gibi oluşacaktır.
POST /addUser ... username=anilbas&password=C0kGizl!S1fr3&displayName=Anıl+Baş&emailAddress=test@testmail.co |
Bu normal istek controller tarafından karşılandığında UserModel sınıfımıza doğrudan bu parametreler eşleştirilecektir.
Öznitelik |
Değer |
username |
anilbas |
password |
C0kGizl!S1fr3 |
displayName |
Anıl Baş |
emailAddress |
test@testmail.com |
organizationalUnit |
test |
organization |
test |
locality |
Istanbul |
stateProvince |
Istanbul |
countryCode |
TR |
isAdmin |
|
isEnabled |
|
Burada dikkatimizi bir noktanın çekmesi gerekiyor. Bizim UserModel sınıfımızdaki “isAdmin” ve “isEnabled”öznitelikleri ne oldu? Bu öznitelikleri istek üzerinde göndermediğimizde arka plandaki iş akışına göre varsayılan değerde tutulabilir veya boş bırakılabilir. Peki ya biraz kötü niyetli düşünürsek, nerelere varabiliriz? Bu özniteliklerin üzerine yazma ihtimalimiz olabilir mi? Aynı isteği aşağıdaki şekilde tetikleyelim.
POST /addUser ... username=anilbas&password=C0kGizl!S1fr3&displayName=Anıl+Baş&emailAddress=test@testmail.co |
Öznitelik |
Değer |
username |
anilbas |
password |
C0kGizl!S1fr3 |
displayName |
Anıl Baş |
emailAddress |
test@testmail.com |
organizationalUnit |
test |
organization |
test |
locality |
Istanbul |
stateProvince |
Istanbul |
countryCode |
TR |
isAdmin |
true |
isEnabled |
|
Bu noktada artık “isAdmin” özniteliğini de ön yüzden eklenmemesine rağmen üzerine yazarak kendi kullanıcımızı backend sunucusunda admin yetkileri ile ekleyebildik. Yani uygulama üzerinde yönetici haklarını kendi hesabımıza da alabildik. Temelindeki kök neden aslında basit, değil mi?
Yazının başında sömürmesi zor olan bir zafiyet olduğundan bahsetmiştim. Zafiyeti sömürebilmek için arka planda UserModel sınıfındaki özniteliği bilmemiz gerekiyor. Farklı bir uygulamada bu öznitelik isAdmin değil de doğrudan admin de olabilir. Bunu saldırgan tarafından bilmek ise çok zor.
Saldırgan bu zafiyeti şu durumlarda sömürebilir;
1- Arka planda sınıfa bağlı özniteliğin ismini tahmin edebilmeli veya,
2- Kaynak koduna erişimi varsa (açık kaynak kodlu projeler için bu ihtimal yüksek ya da farklı bir zafiyeti sömürerek kaynak kodu görebiliyorsa mümkün olabilir) ve hassas alanlar için modelleri inceleyebilmeli,
3- Bu alanları içeren sınıfın boş bir constructor yapısı olmalı.
Zafiyetin çözümü için;
1- Eşlenmesine izin verilen, hassas olmayan alanları beyaz listeye ekleyin.
2- Eşlenmesine izin verilmeyen, hassas alanları kara listeye alın.
3- Veri Aktarım Nesnelerini (DTO) kullanın. DTO yapıları her işlem için farklı öznitelikleri kullanmanıza olanak tanır.
GitHub Örnek Olay
2012 yılında, mass assignment zafiyeti kullanılarak GitHub’a saldırıda bulunuldu Bir kullanıcının publickey bilgisini herhangi bir kuruluşa yüklemesi ve böylece respositorylerinde değişiklikler yapabilmesi bu saldırıya olanak sağladı. GitHub'ın Blog Yazısı.
Bir sonraki içerik: "Mass Assignment Zafiyetinin Sömürülmesi"
Kaynaklar
C# .NET MVC ortamında geliştirilmiş bir projede formdan gelen veriyi doğrudan veritabanı modeli üzerine almak yerine viewmodel kullanmak daha doğru olacaktır. Kullanıcı ve veritabanı arasındaki ilişkinin doğrudan değilde soyut bir katmandan aracılığıyla sağlanması gereksinimi buna cevap niteliğindedir.