PHP'de Güvenlik

TreXiaNos
26-05-2009, 10:39   |  #1  
OP Üye
Teşekkür Sayısı: 0
85 mesaj
Kayıt Tarihi:Kayıt: May 2009

1 - Kod Enjeksiyonu (Code İnjection):

  Kullanıcıdan girdi istenen form  yapıları veya adres satırı ile yapılan saldırılara code injection saldırıları denir. Saldırgan form veya adres satırı yoluyla değişkenlere ve dolayısıyla değişkenleri kullanan sorgulara çeşitli kodlar gönderir ve eğer kullanıcıdan alınan veriler filtrelenmeden işleme konuluyorsa bu kodlar sistemde çalışırlar ve böylece güvenlik açığı meydana gelir.

  Açığın oluşumu konusunda internette fazlasıyla kaynak mevcut ama ben yine de açığın oluşumunu sql üzerinden basitçe anlatacağım çünkü bizim için önemli olan kısım nasıl korunacağımız…

  Örneğin bir login sayfamız var ve buradan kullanıcıların nicklerini ve şifrelerini girecekleri  bir formumuz var.Arka planda ise şöyle bir kod yapısı mevcut;

$nick=$_POST[“nick”];

$sifre=$_POST[“sifre”];

$sql= mysql_query(”select * from kullanicilar where nick=’$nick’ and sifre=’$sifre’ ”);

Normal şartlarda eğer şifre ve nick doğruysa sistem true değer döndürecek, bir tanesi bile yanlışsa sistem false değer döndürecektir.Peki ama giriş panelini açan kişinin niyeti farklıysa…

Diyelim nick ve şifre bölümüne şöyle bir kod girildi. ‘ or ’1’=’1

Kod yapımız şöyle bir hal alacaktır;

$sql=mysql_query(”select * from kullanicilar where nick=’ ‘ or ’1’=’1’ and sifre=’ ‘ or ’1’=’1’ ”);

Yani bu ne demek? Nick değeri boşsa yada 1=1 ise ve sifre değeri boşsa yada 1=1 ise Kullanicilar tablosundaki bütün verileri çek ! Nick ve şifre değerlerimiz boş değil ancak her zaman 1=1.Bu yüzden sistem kullanicilar tablosundaki bütün verileri çekecek ve true sonuç döndürecektir.Yani sisteme id si en başta olan kullanıcı olarak giriş yapılacaktır.Ki bu genelde admin olur :)
  Ayrıca bu sistem login sistemi olmasa mesela bir yorum modülü olsa bile saldırgan  ‘   gibi sql için önemli karakterleri sql sorgusuna sokarak kodumuza hata verdirebilir ve bu kodlardan yola çıkarak da daha kritik noktalara erişebilir.(Hata Bazlı SQL İnjeksiyon)

Peki bundan nasıl korunacağız?

1-Hata Kodlarını Gizleme:Sorgumuz herhangi bir sorun ile karşılaştığında hata kodlarını ekrana bastırmasını engellemek bir nebze olsun güvenli kılacaktır. Bunun için sorgu fonksiyonlarının başına @ işareti koymamız yeterli.

$sql=@mysql_query(”select * from kullanicilar where nick=’$nick’ and sifre=’$sifre’ ”);

Ancak hata kodlarını saklamak bizi tamamen korumaz çünkü;

-PHP açık kaynak bir yazılımdır yani kodlarımızı başkaları da görüyor olabilir dolayısıyla sistemimizin zayıflıklarını kodlara bakarak belirleyebilirler.

-Blind Sql injeksiyon saldırıları ile hata kodları olmaksızın deneme/yanılma,sayfa yüklenme süresi vs gibi etkenlere bakarak sorgumuzun hata verdiğini anlaşılabilir.Ki bu konuda yazılmış programlar saldırganın işini oldukça kolaylaştırır.Dakikada yüzlerce sorgu gönderip tablo yapımızı belirleyen programlar internette mevcut.

2-Veri Filtreleme:Bu konuda alınacak en önemli önlemdir.Kullanıcıdan gelen parametreler mutlaka filtrelenmelidir.HTML kodları,JavaScript kodları,SQL için özel anlam ifade eden karakterler filtrelenmeli ondan sonra işleme tabi tutulmalıdır.Bu konuda örnek bir fonksiyon yazalım…(Tabi PHP5 ile :) )

// temizle.php

class veritemizle{

                public $veri;

                public $temizveri;

                public $temizle;

                function temizle($veri){

                        $this->veri=$veri;

                         $this->temizle=array(

                 ’<’ => ’’,

                 ’ " ’ => ’’,

                 ’>’ => ’’,

                " ’ " => ’’,

                ’-’ => ’’,                        

          );

          $this->temizveri =strtr($this->veri,$this->temizle);

         return true;

                }

}

Bu fonksiyonu sistemimize uygulayarak kodumuzu güvenli hale getirelim…

İnclude “temizle.php”;

$temizlik=new veritemizle();

$temizlik->temizle($_POST[“nick”]);

$nick=$temizlik->temizveri;

$temizlik->temizle($_POST[“sifre”]);

$sifre=$temizlik->temizveri;

$sql=@mysql_query(”select * from kullanicilar where nick=’$nick’ and sifre=’$sifre’ ”);

Artık sistemimiz güvende :)

Peki fonksiyonumuz ile ne yaptık?

Fonksiyonumuz giriş verimizdeki    <  > ‘ – “ gibi bizim için tehlike arz edebilecek karakterleri verimizden temizledi. Siz de fonksiyonu kendinize göre düzenleyerek karakter aralığını değiştirebilirsiniz.

Fonksiyon kodları : http://rapidshare.com/files/207655960/temizlik.txt.html

Yakında Daha Geniş Makalelerde yayınlayacağım.

PcMaKeR
26-05-2009, 11:28   |  #2  
PcMaKeR avatarı
Yıllanmış Üye
Teşekkür Sayısı: 6
8,935 mesaj
Kayıt Tarihi:Kayıt: Eki 2005

PHP için güzel bir algoritma SQL özel karakterlerini bloklamak.

yazılarını takip ediyorum phpcisin sanırım ama asp.net te ise böyle bir derdin yok mesela örnek bak:

SqlConnection con=new sqlConnection("vtbağlantısı");
con.Open();
SqlCommand cmd=new SqlCommand("select userid from Users where (UserName=@UserName) and (Password=@Password)",con);
cmd.Parameters.Add("@UserName",UserName.Text);
cmd.Parameters.Add("@Password",Password.Text);

if(cmd.ExecuteNoneQuery()>0)
{
Response.Redirect("Uyeyeozel.aspx");
}
else
{
Hata.Text="Kullanıcı Girişi Başarısız!";
}


cmd.Parameters.Add("@UserName",UserName.Text);
cmd.Parameters.Add("@Password",Password.Text);

parametreli sorgu olduğu için istediği kadar sql enjection yapsın banamısın demez ;)

Son Düzenleme: PcMaKeR ~ 26 Mayıs 2009 11:28
TreXiaNos
26-05-2009, 11:32   |  #3  
OP Üye
Teşekkür Sayısı: 0
85 mesaj
Kayıt Tarihi:Kayıt: May 2009

Benim alanım tümünü kapsıyor :) Php konusundaki anlatımlarımdan sonra Asp.Net'ede geçip paylaşımlarda bulunacam. Tabiki Asp.net çok ayrı bir dil Php ile çok fark var aralarında

PcMaKeR
26-05-2009, 11:37   |  #4  
PcMaKeR avatarı
Yıllanmış Üye
Teşekkür Sayısı: 6
8,935 mesaj
Kayıt Tarihi:Kayıt: Eki 2005

Aynen çok fark var. ASP.NET .NET i kapsıyor o yüzden güç olarak php den yüksek. Ama php normal asp.net te hiç optimizasyon yapmazsan php daha hızlı çalışır. çoğu kişi asp.nette tek satır kod kullanmadan site yapar çok yavaş çalışır ama ben Pl, BL, ve DAL classlarını tam oturtarak(elle yazdığın için daha iyi oluyor) daha hızlı çalıştırırım php den.