• 12-11-2007, 21:12:56
    #1
    Önceden yazdığım ufak tefek şeyleri buraya da ekleyim dedim
    Copy/paste yaptığım için format biraz kötü oldu....
    -----
    Php scriptleri genelde diğer programlama dillerinde olduğu gibi kullanıcıdan veri alır,işler ve çıktı üretirler. Php scriptlerinde güvenliği sağlamak açısından ilk adım kullanıcıdan veriyi alma aşamasında yapılır. Güvenli ve doğru veri almalıyız ki diğer adımlarda buna dayanarak doğru doğru ve güvenli sonuçlar versin.
    Tabii tüm girdileri kontrol edip onaylayabileceğimiz tek bir php fonksiyonumuz yok. Her türlü girdiyi kontrol edip doğrulamak için özel fonksiyonlar yazmamız gerekebiliyor. Örneğin sayısal veriler atama sırasında kontrol edilebilirken string türü veriler için aynı şeyi söylemek mümkün değil.
    Şimdi güvenlik kısmına biraz göz atalım;
    Php programcıları genelde kullanıcıdan gelen verileri ‘register globals’ ile ele alırlar. Register globals scripte gelen parametrelerle aynı isme sahip değişkenler oluşturur. Örneğin scriptimize ahmet.com/url.php?isim=ahmet gibi bir adresten erişilirse script içinde $isim="ahmet" ataması yapılmış gibi yorumlanacaktır.
    Register globals özelliği scripte gelen parametreleri almak için kolay bir yöntem olmasına rağmen güvenlik açıklarına yol açabilecek bir yapısı vardır. Script sadece tek bir şekilde parametre almadığı için gelen parametrelerin birbiri üzerine yazılması gibi bir sorun oluşabilir. Örneğin hem url üstünden hemde cookie içinden “id" adında bir parametre gelirse bu iki değikenden biri diğerinin üzerine yazılır. Bu üstüne yazma işleminde öncelik sırasını php.ini dosyası içinden değiştirme şansına sahipsiniz. Bu ayar eski versyionlarda gpc_order, yeni versiyonlarda ise variables_order olarak kullanılmaktadır. gpc_order’ın default olarak değeri Get Post ve Cookie’dir. Bu demek oluyor ki en yüksek öncelikli parametre kaynağı cookie’dir. Yani aynı isimde iki parametre hem cookie hemde get methoduyla gelirse cookie’den gelen değişken değeri get ile gelen değişkenin üstüne yazılacaktır. Yeni sürümlerde bulunan variables_order’ın default ayarı EGPCS şeklindedir. system Environment , Get , Post, Cookie ve Server environment. Burada da Server değişkenleri en yüksek önceliktedir. Bu karmaşadan kurtulmanın bir yolu olarak değişkenlere bir önad eklemek olabilir. Örneğin post ile gelecek verileri isimlendirken “p_" (ör: p_id) kullanabilirsiniz. Ancak bu yöntem de büyük uygulamalarda ve ortak çalışılan projelerde pek kullanışlı değildir ve karmaşaya sebep olabilir.
    Scripte gelen değişkenleri almanın başka bir yolu iste $HTTP_GET_VARS, $HTTP_POST_VARS ve $HTTP_COOKIE_VARS dizilerini kullanmaktır. Bu yöntem kullanıldığında parametre kaynaklarını biribine karışmadan rahatlıkla kullanabilirsiniz. Tabii işin birde kötü yanı bulunmakta, bu şekilde aldığınız değişkenler global değişken değildirler ve fonksiyonların içinden kullanmak oldukça zor olur. Bunun için $GLOBALS[’HTTP_GET_VARS’][’id’] şeklinde bir yazım kullanmak zorundasınız ki görebileceğiniz gibi hiç kullanışlı bir yöntem değildir.
    Değişkenleri birbiri üstüne yazdırmadan alsak bile hala sorunlar devam etmektedir. Aşağıdaki örneğe bir göz atalım:
      <?php 
    if(giris_yapildi())
     $logged= TRUE;
     if($logged)
     
     ?>
    Burada giris_yapildi fonksiyonunun sonucuna göre $logged değişkenine True değeri atanacaktır veya atanmayacaktır…
    Register globals’in açık olduğu düşünülürse… Üst tarafaki kodda kullanıcı giriş yapmamışsa yani atama yapılmazsa bu ($logged) değer boş olacaktır, dışarıdan herhangi bir input methodu ile bu değişkene değer atanabilir ve sanki biz kod içinden atama yapmışız gibi işlem görülebilir.
    Eğer bu gibi atama yapılmamış durumlarda php motorunun hata mesajı üretmesini istiyorsanız error_reporting fonksiyonu ile güvenliği arttırabilirsiniz. error_reporting(E_ALL | E_STRICT); şeklinde bir fonksiyon çağrısı php motorunun en ufak hatalarda (veya hata oluşturabilecek durumda) size mesaj iletmesini sağlar. Örneğin üstte gördüğümüz kodda oluşan açıktaki gibi tanımlanmamış değişkenlerin kullanılmasında hata mesajı üretilecektir.
    Tanımlanmamış değişkenlere değer atamada error_reporting bir güvence sağlasa bile yanlış kullanımlar sonucunda istenmeyen durumlara yol açabilecek kodlama stilleri olabilir. Aşağıda ki örnek olayı daha iyi açıklar sanırım:
    <?php 
    $uye_id[]="95";
     $uye_id[]="96";
    
     foreach($uye_id as $deger ){
     mysql_query("DELETE FROM users  WHERE id=".(int)$deger);
     }
     ?>
    Yukarıda ki gibi kodlanmış bir scripte script.php?uye_id[]=1&uye_id[]=2 adresinden ulaşılırsa neler olacağını tahmin edebilirsiniz sanırım. Sileceğimiz üye numaralarının olduğu diziye önceden değer ataması yapıldı ve biz sadece üstüne ekleyip silme işlemini yaptık.
    Bunun gibi bir hatayı engellemek için dizi değişkenlerine değer atama yapmadan önce aşağıdaki gibi diziyi kendimizi yaratıp sıfırlamamız gerekli.
    <?php $uye_id= array();
     $uye_id[]="96";
     foreach($uye_id as $deger ){
     mysql_query("DELETE FROM users  WHERE id=".(int)$deger);
     }
     ?>
    Bu sayede dizimizi kullanmadan önce oluşturup içeriğinin boş olduğuna emin oluyoruz.
    ------------------------
    ------------------------
    Yazının birinci bölümünde anlattığımız bazı açıklardan korunmanın global bir yolu var aslında Php.ini dosyası içinden register_globals anahtarının değerini off yapmak. Bu sayede her türlü parametreye kaynağına ait bir diziden ulaşabilirsiniz. Ayırca bu dizi superglobal olduğundan erişimde herhangi bir sorun yaşamayacaksınız. Bu dizilerimiz : $_POST, $_GET, $_SESSION, $_ENV, $_COOKIE, $_SERVER. Php 4.1 ile gelen bu özellik php 4.2′den itibaren register_globals=off default ayarıyla gelmektedir. Tabii hala birçok server bu özelliği kullanmıyor, veya eski tarzda scripte sahip insanlar bu özelliği kasten kullanmıyorlar. Aksi halde scriptin tekrar elden geçirilmesi gerekli ve bunu göze alamıyorlar.
    Sabit Çözümler
    Sabit (constant) değişkenler global değişkenler olarak kullanılıp uygulamalarda bizlere kullanımı kolay çözümler sunuyorlar. Örnekler üstünde konuyu biraz ineceleyelim:
    <?php define("logged", giris_yapildimi() );
     if(logged)
     
    ?>
    Sabit değişkenlere her alandan (scope) erişilebildindiği gibi bu değişkenler modifiye de edilemez. Ayrıca define fonksiyonuna 3. parametre olarak TRUE değeri yollarsanız değişkenleriniz büyük-küçük harf duyarsız olur (case insensitive) bu sayede yazım hatalarından kaynaklanabilecek bazı sorunlarında üstesinden gelebilirsiniz.
    Sabitler bu kadar toz pembe bir tablo çizsede Php’nin sıkı bir dil olmamasından dolayı kaynaklanan bir açığa yol açabilirler. Eğer tanımlanmamış bir sabit değişkene erişmek isterseniz sonuç olarak size NULL değeri yerine erişmeye çalıştığınız sabit değişkenin adını string olarak verir. Bundan dolayı koşullu ifadelerin içinde kullandığınız sabit değerler tanımlanmadıysa, koşulun sürekli olarak TRUE değeri üretmesine yol açar. Örneğimizde durumu daha iyi anlatacağım sanırım :
    <?php 
    if(logged())
     define("giris_yapti",TRUE);
     if(giris_yapti)
     
    ?>
    if(giris_yapti) -> Bu koşul giriş yapıldsa TRUE(boolean) olarak tanımlanacak, giriş yapılmadıysa giris_yapti(string) olarak tanımlanacak ve if koşulu FALSE (boolean) değer almadığı için her durumda kendine bağlı kod bloğunu yorumlatacak.
    Bu sorunun çözümü için karşılaştırmada türe duyarlı olarak bir eşitlik kontorlü yapılmalıdır.
    <?php if(logged())
     define("giris_yapti",TRUE);
     if(giris_yapti === TRUE)
     
    ?>
    Dikkat ederseniz bu sefer koşulu üç adet eşittir işareti ile sınadık. Bu sayede sadece operatörün iki tarafındanki değerlerin hem tür hemde içerik olarak aynı olması durumunda TRUE değeri dönecektir. Bu değişkenlerin türlerinin eşit olmaması durumunda direk olarak FALSE üretilmesini sağlayacaktır. Tip dönüşümüne gerek kalmadığı için performans artışı da sağlamaktadır.
    Yukarıda bahsettiğim gibi eski kodlarını kullanmaya devam etmek isteyen kişiler register_globals seçeneğine aldırış etmeden eski yöntemle yollarına devam ediyorlardı. Php ekibi bunu göze alarak yeni ayarların bulunduğu server üstünde eski kodların çalışması için bir superglobal dizi daha getirdi. $_REQUEST dizisi get, post ve cookie değerlerine erişebileceğimiz bir dizidir. Tabii ayrı kaynakakları tek bir dizide birleştirdiği için üstüne yazma (merge) sorunu burada da ortaya çıkıyor. Aynı ada sahip get, post veya cookie değişkenleri yine birbirinin üstüne yazılmaktadır.
  • 13-11-2007, 00:47:25
    #2
    Kimlik doğrulama veya yönetimden onay bekliyor.
    Güzel Bir Makale Olmuş tebrik Ederim
  • 13-11-2007, 02:50:21
    #3
    Üyeliği durduruldu
    php'ye dönüş mü yaptın güzel makale
  • 13-11-2007, 18:27:25
    #4
    Bunları 2-3 ay önce yazmıştım sanırım ama herhangi 1 foruma göndermemiştim. Dün birden aklıma geldi gönderiverdim
    Aslında devamını da yazacaktım, plan & program haızırdı ama php işine ara verdim Zaman zaman dönerim umarım...