Dosya Yükleme Modüllerinin Güvenliğini Sağlamak

Merhaba

Web uygulamalarının dosya yükleme modülleri, web uygulamalarının en zayıf halkalarından bir tanesidir. Yapılacak herhangi bir hata, sunucu kontrolünün doğrudan saldırganların eline geçmesi ile sonuçlanabilir. Bu nedenle yazılım geliştiricilerine yönelik olacak bu blog yazısında, en çok yapılan hatalara ve benim kanaatime göre en az bilinen saldırı yöntemlerine değinilecektir. 

Client Side Tampering

Bu terim spesifik olarak dosya yükleme modüllerinin haricinde, web uygulama saldırılarının temel konseptini oluşturmaktadır. Özet olarak “Kullanıcıya gönderdiğiniz verilerin hiçbirine bir daha güvenemezsiniz!” anlamına gelen bu terim, güvenli uygulama geliştirmenin temellerinden bir tanesidir.

Bizim ele aldığımız dosya yükleme modülünü, Client Side Tampering nezdinde incelersek güvenemeyeceğimiz veriler aşağıdaki şekildedir.

  • Yüklenen dosyanın ismi.
  • Yüklenen dosyanın Content-Type bilgisi.

Bu iki değer yazılım geliştirici olarak white listing yapabilme imkanımızın olduğu noktalardır. Dosya ismi verisi client side tampering ile herhangi bir şey içerebilir. Aynı şekilde Content-Type değeride, saldırgan .exe dosyası yüklüyor olsa bile image/jpeg olarak gözükebilir. Bu nedenle bu iki veriye kesinlikle güvenilmemelidir!

Dosya uzantısı

Bir önceki paragrafta white listing teriminden bahsetmiştik. Dosya yükleme modüllerini geliştirirken ilk başta yapılması gereken dosya uzantısı için white listing işlemidir. Örneğin; kullanıcının yüklemek istediği dosyanın ismi mehmet.jpeg ise dosya isminin uzantısının .jpeg olduğu tespit edilerek izin verilen dosya uzantılarından birisi olup olmadığına bakılmalıdır.

$file_parts = pathinfo($filename);
switch($file_parts['extension'])
{
    case "jpg":
    break;

    case "exe":
    break;

    case "": // Handle file extension for files ending in '.'
    case NULL: // Handle no file extension
    break;
}

Bu işlemi yukarıdakine benzer kod blokları geliştirerek yapabilirsiniz. Veya kullandığınız frameworkün bu tür işlemler için sunduğu sınıflar, fonksiyonlar kullanılabilir.

Lütfen dosya ismini nokta ( . ) karakterine göre parse edip dosya uzantısı verisi oluşturmamaya özen gösteriniz. mehmet.jpeg.php gibi bir dosya ismi ataması sizin kontrolünüzü atlatabilir.

Content-Type bilgisi

Her dosya yükleme işleminde HTTP talebinde gönderilen bir bilgidir. Bu bilgi internet tarayıcısı tarafından tespit edilir ve gönderilen talebe eklenmektedir. Client Side Tampering ile bu bilgi değiştirilerek sunucu tarafındaki doğrulamalar atlatılabilir. Yani kontrol olarak Content-Type bilgisi üzerinden doğrulamalar yapılmalıdır ama yeterli değildir.

Sizlere bir soru ?

Dosya uzantısını belirttiğiniz gibi doğru şekilde kontrol ediyoruz ve sadece “.jpeg” kabul etmekteyiz. Ayrıca her ihtimale karşı Content-Type bilgisinide kontrol etmekteyiz ve sadece “image/jpeg” kabul ediyoruz. Uygulamamıza upload modülü üzerinden herhangi bir saldırı yapılabilir mi ?

Bu soruya cevap vermeye çalışmanızı rica ediyorum. Biraz düşünün.

SWF Dosyaları

Flash gibi yapılara destek veren internet tarayıcıları için dosya uzantısı ve content-type verileri hiçbir şey ifade etmemektedir. Uzantısı farketmeksizin bir flash dosyasını <object> tagi üzerinden çağırırsanız, çağırılan dosya içerik olarak flash uygulaması olduğu sürece herhangi bir problem olmadan execution tamamlanmaktadır. Buda ciddi bir başka güvenlik problemine sebeb olacaktır.

Saldırı Adımları

  1. Saldırgan hedef web sitesine resim.jpeg adında ve uzantısında hazırladığı SWF dosyasını upload eder.
    1. Upload işleminde extension .jpeg whitelisting doğrulaması geçilir.
    2. Content-type doğrulamasıda client side tampering ile atlatılacaktır.
  2. Yüklenen dosya www.hedef.com/resimler/resim.jpeg olarak hedef sunucuya yerleştiğini kabul edelim.
  3. Saldırgan kendi kontrolünde olan saldırgan.com olan web sitesinde az önce yüklediği resim.jpeg dosyasını “application/x-shockwave-flash” tipi ataması ile <object> olarak çağırır.
  4. Masum kullanıcı saldırgan.com adresine giriş yapar.
  5. saldırgan.com adresi kullanıcıya www.hedef.com/resimler/resim.jpeg adresinde SWF dosyasını çağırtır ve SWFe verilen komutları yerine getirir.
  6. Bu sayede hacker, masum kullanıcılara farkından olmadan hedef.com adresi için HTTP talebi aksiyonları oluşturtabilir. Bu talepler masum kullanıcının oturumu ile gerçekleştirilecektir CSRF kontrolü atlatılmış olacaktır.

Yani az önceki sorumuzun cevabı; HAYIR. olmalıdır.

Bu saldırı senaryosunu daha net anlatabilmek adına, aşağıdaki kodun saldırgan.com tarafından kullanıcıya gönderilen HTML içerikte olduğunu düşünebilirsiniz.

<object style="height:1px;width:1px;" data="www.hedef.com/resimler/resim.jpeg" type="application/x-shockwave-flash" allowscriptaccess="always" flashvars="c=read&u=blablabla"></object>

 Gerçek hayattan örnek

Bu blog yazısına yazmama sebeb olan ve geçtiğimiz günlerde Paypal firmasında tespit edilen güvenlik açığının analizini okumanızı şiddetle tavsiye etmekteyim.

http://www.multibear.com/2014/12/taking-over-paypal-accounts-with-flash.html

Çözüm

En güzel çözümlerden birisi file upload ile yüklenen dosyalara erişimin farklı bir subdomain üzerinden yapılmasıdır. Az önce ifade ettiğim senaryoya göre static dosyalara aynı domain üzerinden değil, farklı bir subdomain üzerinden şu şekilde erişim gerçekleştirilebilir http://dosya.hedef.com/resimler/resim.jpeg

Bir diğer çözüm ise file upload ile yüklenen dosyalara erişim talebi geldiğinde, HTTP cevabın Content-Disposition: attachment;  bilgisinin eklenmesidir.