Veritabanına gönderilen her bir değişken mysql_real_escape_string()
işlevinden geçirilerek sql enjeksiyonlarına karşı önlem alınabilir.
Bu işlev veritabanları için özel anlamı olan karakterleri escape-kurtarma işlemine tabii tutar,
bu karakterlerden bazıları: \n, \r, \, ‘, ”
Aşağıdaki gibi kullanıcı adı ve şifre alanlarından oluşan bir giriş formumuz olsun:
1 2 3 4 5 6 7 8 9 10 11 12 | <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>mysql_real_escape_string</title> </head> <body> <form name="form1" action="" method="post"> Kullanıcı adı:<input type="text" name="kullanici_adi" value="" /> <br /> Şifre<input type="password" name="sifre" value="" /> <br /> <input type="submit" value="gönder" name="gonder" /></div> </body> </html> |
Kullanıcının formdan aşağıdaki bilgileri gönderdiğini varsayalım.
1 2 | $_POST['kullanici_adi'] = 'zihni'; $_POST['sifre'] = "' OR ''='"; |
Kullanıci adi ve sifre verilerinin veritabanında olup olmadığını kontrol edelim
1 2 3 4 5 6 7 8 | <?php $sorgu = "SELECT * FROM kullanicilar WHERE kullanici_adi='{$_POST['kullanici_adi']}' AND sifre='{$_POST['sifre']}'"; $sonuc = mysql_query($sorgu) or die(mysql_error()); $satir = mysql_fetch_array($sonuc); echo $satir['kullanici_adi']; ?> |
mysql’e gönderilen sorgu aşağıdaki gibi olur:
1 | SELECT * FROM kullanicilar WHERE kullanici_adi='zihni' AND sifre='' OR ''='' |
Görüldüğü gibi sifre geçersiz olsa bile sorgu sonucu başarılı olur.
Eğer formdan gelen bilgileri mysql_real_escape_string() işlevinden geçirdikten sonra veritabanına gönderirsek:
1 2 3 4 5 6 7 8 9 10 11 | <?php $sorgu = sprintf("SELECT * FROM kullanicilar WHERE kullanici_adi='%s' AND sifre='%s'", mysql_real_escape_string($_POST['kullanici_adi']), mysql_real_escape_string($_POST['sifre']) ); $sonuc = mysql_query($sorgu) or die(mysql_error()); $satir = mysql_fetch_array($sonuc); echo $satir['kullanici_adi']; echo $sorgu; ?> |
mysql’e gönderilen sorgu aşağıdaki gibi olur ve bir sonuç döndürmez.
1 | SELECT * FROM kullanicilar WHERE kullanici_adi='zihni' AND sifre='\' OR \'\'=\'' |
Küçük bir not düşeyim; mysql_real_escape_string’den geçirilipde veritabanına eklenmiş verileri kullanırken stripslashes($mysqlden_gelen_veri); şeklinde kullanmak lazım. aksi taktirde Beyza’nın Kızları isimli filmi ekrana Beyza\’nın Kızları şeklinde basar.
Eğer php.ini dosyasında, magic_quotes_runtime =Off olarak set edilmiş ise, ki default off olarak geliyor, stripslasshes kullanmaya gerek yok.
Ama magic_quotes_runtime =On olarak set edilmiş ise dediğin gibi stripslashes kullanmak gerekli.
prepared ifadeler kullanılamıyorsa iyi bir alternatif..