Şub 18th, 2009
yazar Zihni.
Betiklerimize istemediğimiz yerlerden form verilerinin gönderilmesiyle ortaya çıkar.
Aşağıdaki gibi bir formumuz(form.php) olsun:
<form action="formIsle.php" method="POST">
<input type="radio" name="medeniHali" value="bekar" checked="checked">
<input type="radio" name="medeniHali" value="evli">
<input type="radio" name="medeniHali" value="dul">
<input type="submit" value="Gönder" />
</form>
Bu formu işleyen sayfamız(formIsle.php) ise aşağıdaki gibi olsun, formdan gelen medeni hali bilgisini yazdırıyor.
1
2
3
4
| <?php
echo $_POST['medeniHali'];
// Çıktı: bekar
?> |
Saldırganın aşağıdaki formu(form.php) kendi bilgisayarından gönderdiğini varsayalım. Formun action özelliğine tam adresi yazıyor.
1
2
3
4
| <form action="http://www.siteadresi.com/formIsle.php" method="POST">
<input type="text" name="medeniHali" value="yalancı">
<input type="submit" value="Gönder" />
</form> |
Form işleyen(formIsle.php) sayfamız yukarıda gönderilen formu işler.
1
2
3
4
| <?php
echo $_POST['medeniHali'];
// Çıktı: yalancı
?> |
Medeni hali, bekar-evli-dul değerlerinden birini alması gerekirken, “yalancı” diye bir değer almıştır.
Bunu önlemek için tek kullanımlık bir şifre oluşturulabilir:
1
2
3
4
5
6
7
8
9
10
11
| <?php
$formAnahtar = rand(10000,1000000);
$_SESSION['formAnahtar'] = $formAnahtar;
?>
<form action="http://www.siteadresi.com/formIsle.php" method="POST">
<input type="radio" name="medeniHali" value="bekar" checked="checked">
<input type="radio" name="medeniHali" value="evli">
<input type="radio" name="medeniHali" value="dul">
<input type="hidden" name="formAnahtar" value="<?php echo $formAnahtar; ?>">
<input type="submit" value="Gönder" />
</form> |
Formu işleyen(formIsle.php) sayfamız:
1
2
3
4
5
6
7
| <?php
if($_SESSION['formAnahtar'] == $_POST['formAnahtar'])
echo $_POST['medeniHali'];
else
echo "Bu form başka bir yerden geliyor.";
?> |
Şub 13th, 2009
yazar Zihni.
Kullanıcının betiklerimize html kodu enjekte etmesiyle ortaya çıkar.
Girdi filtrelenmeden çıktı olarak sunuluyorsa bu saldıya uğranabilir.
Aşağıdaki gibi bir formumuz olsun:
1
2
3
4
| <form id="form1" action="" method="post">
<textarea name="mesaj"></textarea>
<input type="submit" value="gönder" />
</form> |
Formdaki mesaj alanına aşağıdaki javascript kodunun enjekte edildiğini varsayalım.
1
2
3
| <?php
<script type="text/javascript">window.location = 'http://www.zihni.net' </script>
?> |
Girdiyi filtrelemeden, aşağıdaki şekilde ekrana yazdırırsak, sayfaya giren her kullanıcıyı istediğimiz siteye yönlendiririz.
1
2
3
| <?php
echo $_POST['mesaj'];
?> |
Yukardaki kodun zararlı etkilerinden korunmak için girdiyi htmlentities() işleviyle filtrelememiz gerekir.
1
2
3
| <?php
echo htmlentities($_POST['mesaj']);
?> |
Şub 1st, 2009
yazar Zihni.
Kullanıcı girdilerine güvenilmemeli, betiklerimizin güvenliği için
tüm girdiler filtrelenmelidir.
Örneğin kullanıcıdan yaş bilgisini isteyelim:
Kullanıcıdan beklenen girdi, sayı türünde bir değerdir.
Aşağıdaki kod bu doğrulamayı yapar.
$sonuc = preg_match("/[0-9]{1,3}/",$_POST['yas']);
if($sonuc === true)
echo "Girdi doğrulandı";
else
echo "Girdi sayı değil";
Kullanıcının hayat hikayesini istediğimizi varsayalım, yukardaki gibi bir basit bir doğrulama yapamayız, bunun yerine php nin bize sunduğu temel filtreleme işlevlerinden yararlanabiliriz.
Html tagları sorunlara yol açabilir.
stript_tags() işlevi html etiketlerini yok eder.
$girdi = "<h1>büyük bi başlık</h1><span>span etiketi</span>";
echo strip_tags($girdi);
Yukardaki örneğin çıktısı:
büyük bi başlık span etiketi
Bazı etiketlere izin vermek istiyorsak:
$girdi = "<h1>büyük bi başlık</h1><span>span etiketi</span>";
echo strip_tags($girdi,"<span>");</span>
Yukardaki örneğin çıktısı:
büyük bi başlık <span>span etiketi</span>
htmlentities() işlevi tüm html karakterlerini html entitilerine çevirir.
$girdi = "<h1>büyük bi başlık</h1>";
echo htmlentities($girdi, ENT_QUOTES,'UTF-8');
yukarıdaki örneğin çıktısı:
<h1>büyük bi başlık<h1>
Oca 28th, 2009
yazar Zihni.
Javascripteki ayrılmış kelimeler(reserved words), button ismi ve fonksiyon olarak kullanıldığında çatışma(collision) meydana geliyor.
Hata Mesajı:
1
| this.form.submit is not a function |
“Submit” metodunu kullandığım yer:
1
| <select onchange="this.form.submit();"> |
Buton adı olarak “submit” kulladığım yer:
1
| <input type="submit" name="submit" value="Ekle"> |
Buton adını “submit”ten başka bir adla, örneğin “ekle” olarak değiştirdiğimde sorun düzeliyor.
1
| <input type="submit" name="ekle" value="Ekle"> |
Oca 25th, 2009
yazar Zihni.
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 \'\'=\'' |