Onno Eticaret




php güvenlik açıklarını kapatmak

1 - Giriş Kayıt İletişim gibi formlarda post güvenliği

Arkadaşlar giriş,kayıt,iletişim gibi tüm formlarda veriler post edilirken inputtan gelen tüm verileri süzmeden alıyor çoğu kişi süzmediği içinde saldırgan kişiler html taglarını input içerisine ya da farklı birşeyler yazarak veritabanımıza kayıt ettirmeye çalışabilirler.

//strip_tags(); //tüm html tağlarını temizler

//trim(); // tüm boşlukları temizler

Bunların kullanımları nasıldır peki ?

 
   $gelenveri = $_POST["veri"];
 
   echo strip_tags(trim($gelenveri));

gördüğünüz gibi gelen verileri bu şekilde strip_tags ve trim fonksiyonları ile süzdükten sonra veritabanına kayıt ettirirseniz hiç bir html tagları,javascript tagları çalışmayacaktır ve böylelikle bu güvenlik açığını kapatmış oluyoruz.

2 - GET GÜVENLİĞİ

Arkadaşlar get güvenliği konusunda da strip_tags ve trim geçerlidir yani gelen veriyi aşağıdaki gibi almanızı öneririm.

 
   $gelenveri = $_GET["veri"];
 
   echo strip_tags(trim($gelenveri));
   

Bu sayede tarayıcıdan html taglarını kullanarak bir veri ya da formdan html tagları,javascript gibi tagları gönderemezler gönderseler bile strip_tags hepsini yok edecektir.

Ek olarak get ile switch case işlemlerinde örneğin admin panelinde şöyle bir yapınız var

islemler.php?islem=uyesil&id=123

bakın bu yapıda veriniz var bu düzenleme de olabilir silme de olabilir.Siz yönetim panelinin temasını header.php,footer.php gibi böldüyseniz sadece header.php de $_SESSION["yonetici"] kontrolü yaparsınız fakat bu islem.php de switch case kısmına etki etmeyebiliyor.

Bunu bizzat denedim ve gördüm dışarıdan session oluşmadan veri silinebiliyor.Bundan dolayı tüm case kısımlarında ek olarak session kontrolü yapmanızı öneririm.Örnek kod aşağıdaki gibidir.

  
   $islem = strip_tags(trim($_GET['islem']));
 
   switch($islem){
      
       case 'uyesil':
         if($_SESSION['admin']){
            //islemleriniz
         }
       break;
   
   }
 

Gördüğünüz şekilde tüm case kısımlarında session kontrolü yapmanızı öneriyorum arkadaşlar.

3 - DİZİNLERE DİREKT OLARAK ULAŞILMASININ ENGELLENMESİ

Arkadaşlar bu kısımda bahsettiğim güvenlik açığı ise örneğin yaptığınız projede /css /img gibi klasörleriniz var bu klasörlere dışarıdan /img klasörüne girdiğimiz anda direk içerisinde olan tüm herşey listeleniyor bu hoş bir şey değil ve güvenlik açığı olarak nitelendirilebilecek bir konudur.

Bunun ise bir kaç çözümü var

// ilgili klasörlere içi boş bir index.php atmak klasörlerin listelenmesini engellemenize yardımcı olur

// htaccess üzerinden dosya ya da klasör engellemesi yapabilirsiniz.

// wordpress de ise htaccess dosyasının sonuna Options -Indexes bunu eklerseniz tüm dizinlere erişimi kapatır.

4 - HEADER.PHP FOOTER.PHP GİBİ TEMAYI BÖLDÜĞÜMÜZ DOSYALARA DİREKT OLARAK ERİŞİLMESİNİ ENGELLEME

Arkadaşlar burada bahsettiğim ise örneğin bir temanız var ve parçaladınız temayı ust.php alt.php sag.php sol.php diye ayırdınız diyelim eyvallah tema parçalamak mantıklı olay tabiki eski bişey diyecek halim yok.Ama gel gelelim burada temayı parçalamak yetmiyor.Gözden kaçırdığınız bir nokta var oda şu www.domain.com/ust.php dediğiniz anda sadece üst kısımın geldiğini göreceksiniz aynı şekilde diğer sayfalarıda çagırdığınızda bu sayfalara direkt olarak erişildiğini göreceksiniz.

Şimdi burada ayırdığınız üst alt sağ sol gibi sayfaları çağırdığınız sayfada yani ana sayfada hani atıyorum index.php var bunda require_once "ust.php" dediğiniz sayfada yani şu kodu yazıyorsunuz

define("guvenlik",true);

burada yazdığım güvenlik sadece sabit değişkenin ismi oraya ne yazarsanız yazarsınız size kalmış.Şimdi bunu ana sayfada yazdım asıl sayfada yazdım yani bundan sonra diğer sayfaların en üstüne şunu eklemem gerekiyor.

 echo !defined("guvenlik") ? die("Hacker") : null;

şimdi mesala domainadi.com/ust.php yazdığınız anda die içerisine yazdırdığımız yazı gelecektir.Yani direkt olarak ayırdığımız dosyalara erişemeyecekler.

5 - E-POSTA KONTROLÜ

Evet yine geldik bir e-posta kontrolüne daha şimdi çoğu kimse sadece html tarafında input type="email" şeklinde yapıp geçiyor html tarafında @ eksik diye direk uyarı veriyor fakat sayfa kaynağından type="email" kısmını text yaparak o engeli aşabiliyoruz.Fakat biz bunu hem type="email" tarafında hem de php tarafında kontrol edersek geçilmesi imkansız hale gelecektir.


   
  $eposta = $_POST['eposta'];
 
  if(!filter_var($eposta,FILTER_VALIDATE_EMAIL)){
    
     echo "Eposta yanlış";
 
  }
 

Gördüğünüz gibi php tarafında da kontrol ettirdik böylelikle geçemezler bu kısımı.Ek olarak şöyle bir önerim var tüm üye girişlerinde kullanıcı adı yerine e-posta ile giriş yaptırın.Çünkü kullanıcı adını tahmin etmek kolaydır atıyorum yavuz diye kullanıcı adı üzerine bir ton şifre denemesi yaptırabilir ama o kişinin e-posta adresini bulması zor olur.Bundan dolayı e-posta ile giriş yaptırın.

6 - ÇİFT ŞİFRE GİRİŞİ

Arkadaşlar aslında bunu önlem olarak görmeyebilirsiniz gereksiz olarak görebilirsiniz ama kayıt ve giriş formunda denemenizi ve uygulamanızı öneririm.Burada bahsettiğim şudur kayıt olurken ve giriş yaparken şifreyi iki kez sordurmak birinci ile ikinci girilen şifre birbirine eşit ise devam etsin değilse uyarı versin botlara karşı çok daha etkili olursunuz.Örnek verelim.


   
  $sifre= $_POST['sifre'];
  $sifre2= $_POST['sifre2'];
 
  if($sifre == $sifre2){
    
     echo "şifreler eşleşti";
 
  }else{
     
     echo "Şifreler uyuşmadı";
  }
 

7 - ŞİFREYİ KRİPTOLAMA


   
  $sifre= $_POST['sifre'];
   
  echo md5($sifre); // 32 karakterli kriptolu şifreleme
  echo sha1($sifre): // 40 karakterli kriptolu şifreleme
  echo sha1(md5($sifre)); // iç içe şifreleme 
 

Her scriptimde ve her açıklı olan scriptte kullandığım ve kullanılmasını önerdiğim kodu paylaşıyorum. Bu kod ile sql injection tamamen engellenir.

Aşağıdaki fonksiyonu sayfasına include edin

function veriTemizle($mVar){
    if(is_array($mVar)){
        foreach($mVar as $gVal => $gVar){
            if(!is_array($gVar)){
                    $mVar[$gVal] = htmlspecialchars(strip_tags(urldecode(mysql_escape_string(addslashes(stripslashes(stripslashes(trim(htmlspecialchars_decode($gVar)))))))));  // -> Dizi olmadığını fark edip temizledik.
            }else{
                    $mVar[$gVal] = veriTemizle($gVar);
            }
        }
    }else{
        $mVar = htmlspecialchars(strip_tags(urldecode(mysql_escape_string(addslashes(stripslashes(stripslashes(trim(htmlspecialchars_decode($mVar))))))))); // -> Dizi olmadığını fark edip temizledik.
    }
    return $mVar;
 
 
}

Fonsiyonu sayfalarınızda aşağıdaki gibi kullanabilirsiniz.

$_GET = veriTemizle($_GET); // -> GET verilerini temizledik.
$_POST = veriTemizle($_POST); // -> POST verilerini temizledik.
$_SESSION = veriTemizle($_SESSION); // -> SESSION verilerini temizledik.
$_COOKIE = veriTemizle($_COOKIE); // -> COOKIE verilerini temizledik.