• 22-09-2016, 23:29:57
    #1
    Kimlik doğrulama veya yönetimden onay bekliyor.
    Merhaba arkadaşlar. Aşağıda bir kod var. Bazı sitelerde PDO çok güvenlidir. Bu şekilde kullanabilirsiniz yazmışlar fakat benim aklıma takıldı. En azından quote dan geçirmek gerekmez mi?

    $ilet=$db->prepare('INSERT into contact_form name = :name, mail = :mail, tel = :mobile, mesaj = :message');
    					$ilet->execute(array("name" => "$_POST[name]",
    										"message" => "$_POST[message]",
    										"mail" => "$_POST[mail]", 
    										"mobile" => "$_POST[mobile]");
  • 22-09-2016, 23:42:14
    #2
    Merhabalar hocam,

    quote tam olarak ne işe yarıyor acaba?

    Teşekkürler.
  • 23-09-2016, 09:51:22
    #3
    Tırnak işaretleri içine alsanızda sql enjeksiyona maruz kalabilirsiniz.

    Mesela:

    $b = $a->prepare('SELECT * FROM uyeler WHERE yas = :yas AND cinsiyet = :cinsiyet;');

    şeklinde bir sorgumuz olsun. Haliyle yas koşulumuz SAYISAL(integer), cinsiyet koşulumuz DİZGESEL(string) olacaktır.

    Eğer biz:

    $c = $b->execute([ yas => $_POST['yas'], cinsiyet => $_POST['cinsiyet'] ]);

    şeklinde yaparsak. Ayvayı yedik demektir. Bunu önlemek için PDO'nun bindParam ya da bindValue methodlarını kullanacağız.

    $b->bindParam('yas', $_POST['yas'], PDO::PARAM_INT);
    $b->bindParam('cinsiyet', $_POST['cinsiyet'], PDO::PARAM_STR);
    $c = $b->execute();


    şeklinde yaparsak herhangi bir sql enjeksiyona maruz kalmayız. PDO sorguya hem ilgili alanları tırnak işaretlerine alacaktır hemde escape işlemini uygulayacaktır.

    Yukarıda verdiğim örnekte bindParam ilgili değişkeni referans/pointer olarak kullanır. bindValue ilgili değişkenin içindeki değeri alır.

    bindParam:
    $yas = 20;
    $cinsiyet = 'k';

    $b = $a->prepare('SELECT * FROM uyeler WHERE yas = :yas AND cinsiyet = :cinsiyet;');

    $b->bindParam('yas', $yas, PDO::PARAM_INT);
    $b->bindParam('cinsiyet', $cinsiyet, PDO::PARAM_STR);

    $yas = 25;
    $cinsiyet = 'e';
    $c = $b->execute(); // $yas = 25, $cinsiyet = 'e' olarak kabul edecektir.


    bindValue:
    $yas = 20;
    $cinsiyet = 'k';

    $b = $a->prepare('SELECT * FROM uyeler WHERE yas = :yas AND cinsiyet = :cinsiyet;');

    $b->bindValue('yas', $yas, PDO::PARAM_INT);
    $b->bindValue('cinsiyet', $cinsiyet, PDO::PARAM_STR);

    $yas = 25;
    $cinsiyet = 'e';
    $c = $b->execute(); // $yas = 20, $cinsiyet = 'k' olarak kabul edecektir.


    Yani kısaca bindParam ile bindValue arasındaki fark:

    bindParam: execute methodu çalıştırıldığı andaki değerleri kullanır.
    bindValue: bindValue methodu çalıştırıldığı andaki değerleri kullanır.
  • 23-09-2016, 23:01:13
    #4
    Obsidya adlı üyeden alıntı: mesajı görüntüle
    Tırnak işaretleri içine alsanızda sql enjeksiyona maruz kalabilirsiniz.

    Mesela:

    $b = $a->prepare('SELECT * FROM uyeler WHERE yas = :yas AND cinsiyet = :cinsiyet;');

    şeklinde bir sorgumuz olsun. Haliyle yas koşulumuz SAYISAL(integer), cinsiyet koşulumuz DİZGESEL(string) olacaktır.

    Eğer biz:

    $c = $b->execute([ yas => $_POST['yas'], cinsiyet => $_POST['cinsiyet'] ]);

    şeklinde yaparsak. Ayvayı yedik demektir. Bunu önlemek için PDO'nun bindParam ya da bindValue methodlarını kullanacağız.

    $b->bindParam('yas', $_POST['yas'], PDO::PARAM_INT);
    $b->bindParam('cinsiyet', $_POST['cinsiyet'], PDO::PARAM_STR);
    $c = $b->execute();


    şeklinde yaparsak herhangi bir sql enjeksiyona maruz kalmayız. PDO sorguya hem ilgili alanları tırnak işaretlerine alacaktır hemde escape işlemini uygulayacaktır.

    Yukarıda verdiğim örnekte bindParam ilgili değişkeni referans/pointer olarak kullanır. bindValue ilgili değişkenin içindeki değeri alır.

    bindParam:
    $yas = 20;
    $cinsiyet = 'k';

    $b = $a->prepare('SELECT * FROM uyeler WHERE yas = :yas AND cinsiyet = :cinsiyet;');

    $b->bindParam('yas', $yas, PDO::PARAM_INT);
    $b->bindParam('cinsiyet', $cinsiyet, PDO::PARAM_STR);

    $yas = 25;
    $cinsiyet = 'e';
    $c = $b->execute(); // $yas = 25, $cinsiyet = 'e' olarak kabul edecektir.


    bindValue:
    $yas = 20;
    $cinsiyet = 'k';

    $b = $a->prepare('SELECT * FROM uyeler WHERE yas = :yas AND cinsiyet = :cinsiyet;');

    $b->bindValue('yas', $yas, PDO::PARAM_INT);
    $b->bindValue('cinsiyet', $cinsiyet, PDO::PARAM_STR);

    $yas = 25;
    $cinsiyet = 'e';
    $c = $b->execute(); // $yas = 20, $cinsiyet = 'k' olarak kabul edecektir.


    Yani kısaca bindParam ile bindValue arasındaki fark:

    bindParam: execute methodu çalıştırıldığı andaki değerleri kullanır.
    bindValue: bindValue methodu çalıştırıldığı andaki değerleri kullanır.
    Çok teşekkürler. Ben ayvayı yemişim demek ki. Hepsini güncellemem gerek şimdi

    Demek ki birkaç kişiye danışmak gerek.
  • 25-09-2016, 16:44:44
    #5
    $_POST İşlemlerini şu fonksiyondan geçirip işlem gördürün sıkıntı çıkmaz;

    $Veri = $_POST["veri"];
    yerine;
    $Veri = p("veri");

    Daha güvenli olur. Burada temizleme işlemleri yapılır.
    function p($par, $st = false){
    	   if ( is_array($_POST[$par]) ){
    		  $_POST[$par] = array_map(function($post){
    			 return trim(addslashes($post));
    		  }, $_POST[$par]);
    		  if ( $st )
    			 $_POST[$par] = array_map('trim', $_POST[$par]);
    		  return $_POST[$par];
    	   } else {
    		  if ($st){
    			 return htmlspecialchars(addslashes(trim($_POST[$par])));
    		  }else {
    			 return addslashes(trim($_POST[$par]));
    		  }
    	   }
    	}
  • 26-09-2016, 03:27:56
    #6
    Kimlik doğrulama veya yönetimden onay bekliyor.
    @Obsidya @asimus

    Yukarıda verilen bilgiler hatalıdır. Prepare edilmiş sorguya gelen parametreler tekrar sorgulanmaz. Bu yüzden sql injection mümkün değildir. Çünkü prepare ile zaten sorgu hazırlanmıştır ve parametre ile sadece ayıklama ve tespit işlemi yapılır. Bu yüzden prepare edilmiş bir sorgu üzerinde çoklu execute yapılabilme imkanı vardır.

    PDO'da bindParam, bindValue SQL Injection engelleme görevi görmezler. bindParam ile bindValue arasındaki en önemli fark PARAM_INPUT_OUTPUT sabitidir. bindParam değişkene bağlı parametre gönderirken, bindValue girilen değerlere göre parametre gönderir. İkisinde de veri tipi belirleme imkanı varken, bindParam çıktı için verinin uzunluğunuda belirlemeyi mümkün kılar.

    mySQL:
    PREPARE stmt FROM "SELECT ?";
    SET @param = "'blablablabla', SQRT(4) as Iki";
    EXECUTE stmt USING @param;
    
    /*
    b4d:
    SELECT 'blablablabla', SQRT(4) as IkiMi
    */
    PDO:
    <?php
    	
    	$PDO = new PDO("mysql:host=localhost; dbname=test; charset=utf8", "root", "");
    	
    	$stmt = $PDO->prepare("SELECT ?");
    	
    	$q = "'blablablabla', SQRT(4) as Iki";
    	
    	$stmt->bindParam(1, $q);
    	$stmt->execute();
    	$Birinci = $stmt->fetch(PDO::FETCH_ASSOC);
    	
    	$stmt->bindValue(1, $q);
    	$stmt->execute();
    	$Ikinci = $stmt->fetch(PDO::FETCH_ASSOC);
    	
    	$stmt->execute(array($q));
    	$Ucuncu = $stmt->fetch(PDO::FETCH_ASSOC);
    	
    	print_r($Birinci);
    	print_r($Ikinci);
    	print_r($Ucuncu);
    	
    	print_r($PDO->query("SELECT " . $q)->fetch(PDO::FETCH_ASSOC));
  • 26-09-2016, 08:15:09
    #7
    PROOYUN adlı üyeden alıntı: mesajı görüntüle
    @Obsidya @asimus

    Yukarıda verilen bilgiler hatalıdır. Prepare edilmiş sorguya gelen parametreler tekrar sorgulanmaz. Bu yüzden sql injection mümkün değildir. Çünkü prepare ile zaten sorgu hazırlanmıştır ve parametre ile sadece ayıklama ve tespit işlemi yapılır. Bu yüzden prepare edilmiş bir sorgu üzerinde çoklu execute yapılabilme imkanı vardır.

    PDO'da bindParam, bindValue SQL Injection engelleme görevi görmezler. bindParam ile bindValue arasındaki en önemli fark PARAM_INPUT_OUTPUT sabitidir. bindParam değişkene bağlı parametre gönderirken, bindValue girilen değerlere göre parametre gönderir. İkisinde de veri tipi belirleme imkanı varken, bindParam çıktı için verinin uzunluğunuda belirlemeyi mümkün kılar.

    mySQL:
    PREPARE stmt FROM "SELECT ?";
    SET @param = "'blablablabla', SQRT(4) as Iki";
    EXECUTE stmt USING @param;
    
    /*
    b4d:
    SELECT 'blablablabla', SQRT(4) as IkiMi
    */
    PDO:
    <?php
    	
    	$PDO = new PDO("mysql:host=localhost; dbname=test; charset=utf8", "root", "");
    	
    	$stmt = $PDO->prepare("SELECT ?");
    	
    	$q = "'blablablabla', SQRT(4) as Iki";
    	
    	$stmt->bindParam(1, $q);
    	$stmt->execute();
    	$Birinci = $stmt->fetch(PDO::FETCH_ASSOC);
    	
    	$stmt->bindValue(1, $q);
    	$stmt->execute();
    	$Ikinci = $stmt->fetch(PDO::FETCH_ASSOC);
    	
    	$stmt->execute(array($q));
    	$Ucuncu = $stmt->fetch(PDO::FETCH_ASSOC);
    	
    	print_r($Birinci);
    	print_r($Ikinci);
    	print_r($Ucuncu);
    	
    	print_r($PDO->query("SELECT " . $q)->fetch(PDO::FETCH_ASSOC));
    Eğer sql injection konusunda engelleme yapmıyorlarsa yaklaşık 5000 satır kodu tekrar güncellemem gerekiyor

    Peki SQL injection dan nasıl kurtulabilirim?

    --R10.NET; Flood Engellendi -->-> Yeni yazılan mesaj 08:15:09 -->-> Daha önceki mesaj 08:13:22 --

    truser adlı üyeden alıntı: mesajı görüntüle
    Merhabalar hocam,

    quote tam olarak ne işe yarıyor acaba?

    Teşekkürler.
    Mesajınızı görmemişim kusura bakmayın. quote tırnak işaretleri arasına alıyor sadece.
  • 26-09-2016, 19:04:44
    #8
    Üyeliği durduruldu
    güncellemek istemiyorsanız _POST ları önceden döngüye alıp oradan str_replace ile temizleyebilirsiniz
  • 26-09-2016, 19:26:12
    #9
    sistem index.php?sayfa=sayfa şeklinde ilerliyor. acaba index.php sayfasına bir temizleme aracı eklesem gelen postları temizler mi?

    bütün kodları incelemek çok zor olacak.