in PHP

Güvenli PHP Uygulamaları – Formların Güvenliği

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.";
?>
facebooktwittergoogle_plusredditpinterestlinkedinmail

Write a Comment

Comment

  1. Gayet mantıklı bir teknik. Ayrıca “referer” da kontrol edilerek böyle bir güvenlik tedbiri alınabilir.

    Sonuçta önemli olan bir şekilde tedbir almak ve her gelen veriyi kabul etmemek olduğu için yapılacak her şey mübahtır diyebiliriz 😉

  2. Bu verdiğiniz örnekte bir tedbir ama her hangi bir developer tool ile çok kolay aşılabilir. Direkt browserdan değiştireleceği için session değerinizde istediğiniz gibi set edilir ve hata yakalanamaz. Bunun yerine formIsle.php içinde $_POST[‘medeniHali’] değikeninin bekar,evli veya dul mu diye kontrol edilmesi daha mantıklı geliyor.

  3. Session bilgilerini veritabanında tuttuğumuzu varsayarsak yukardaki örnek güvenlidir.
    Metin dosyada saklıyorsak, dediğin doğru, pek güvenli olmaz.
    Formda medeni hali gibi bir çok alanın olduğunu varsayarak yazmıştım bu makeleyi, formda sadece medeni hali gibi bir alan varsa, haklısın bu alanı kontrol etmek daha mantıklı.

    Peki senin önerin nedir?

  4. Evrencim sana katılıyorum.
    Kullanıcıdan gelen verilerin tek tek doğruluğunun kontrol edilmesi gerekiyor.
    Bu sistem de bir yazılım kullanılarak aşılabilir.

    Session bilgilerini veritabanında tuttuğumuzu varsayarsak yukardaki örnek güvenlidir.

    demişsin Zihni. Session bilgileri zaten sunucuda tutuluyor ve kullanıcı tarafından erişilemez. Veritabanında ya da text dosyada (text dosya webden erişelemeyecek olduğu sürece) farketmez diye düşünüyorum.

    Yine de güzel bir makale. Bir tartışma konusu 🙂

  5. ne yazıkki aşılamaz sayfaya girdigi anda session u almıs olur browseri kapamadan kendi sayfasına geçer. formu veya betigi calıstırır kaynak kodun,da zaten anahtarda hazır

    bu kadar kolay olsa yahoo google gibi buyuk siteler görsel kontrolle ugrasır mı ?

    bu kod bu konudaki açığı kapatmaz.

  6. session ile yapılıcağına kendimiz bir sayı koyup onu doğrulatsak daha mantıklı bence :)) session ile niye uğraşıyorsunuzki

  7. Bence; bu kod kolay aşılır..?
    Bu form’un olduğu sayfayı kendi web sayfamda çağırırım..!
    Sonrada daha önceden kendi sayfama yazdığım javascript ile hidden elemenin value’sini alır ajax ile istediğim kadar veriyi formIsle.php sayfasına gönderirim.;)
    formIsle.php kayıt yapıyorsa vay haline, bi döngü yazarım her 2 saniyede bir veri gönderrim. Bu da 24 saatte 43200 kayıt demektir.. Şuan aklıma gelen bu, ama daha farklı yöntemlerlede aşılabilir …!
    Bana kalırsa captcha kullanın derim, kod yazarak resimdeki anaktar kelimeyi okumak nispeten zordur…
    Herkese kolay gelsin.. Çalışmalarınızda başarılar dilerim..
    ( Konuyu hortlatmak gibi bi amacım yoktu ama mevzudan ortak bir fikir çıkmadığı için yazim dedim..)

  8. şimdi adam direkt formIsle.php ‘ye girdiği zaman if yapısı true dönderecek.
    bunun için $_SESSION[‘formAnahtar’] veya $_POST[‘formAnahtar’] ‘ ın empty kontrolünün yapılması lazım.