6 Şubat 2014 Perşembe

HTML Hidden Input Field - Güvenlik Çözümü (PHP)

HTML sayfalarında kullandığımız "hidden" tipli form elemanları ile genelde kullanıcının görmesi gerekmeyen ama form submit edildikten sonra yapılacak işlemler için önemli olan verileri içerir. Yani "hidden" tipli alanların kullanım amacı; bir veriyi kullanıcıdan gizlemek yani o verinin incelenmesini veya değiştirilmesini önlemektir. Peki bu veriyi gerçekten saklamak ve form ile gönderildiğinde değişmediğinden emin olmak mümkün müdür? İşte bu konuyla ilgili yapılabilecek en iyi şey verinin anlamsızmış gibi gözükmesini sağlamaktır. Şimdi bunu nasıl yapabileceğimize bakalım:

Aşağıdaki örnekte gösterdiğim gibi hidden olan alanda veri tabanımızdaki bir tablodaki bir veri satırının id alanını saklayabiliriz:

--------------------
<form action = "formu_isle.php" method = "post">
     <input type = "hidden" name = "gizli_veri" value = "1566" />
     <input type = "submit" value = "Formu Gönder" />
</form>
--------------------

"hidden" tipli alan HTML tarafından render edilmediği için "1566" değeri her ne kadar sayfada ilk anda görünmese de sayfa kaynağına bakan bir kullanıcı bu veriyi görecektir ve hatta bu veriyi değiştirerek formu submit edebilir.

Bu durumda bu veriyi şifrelenmiş bir şekilde koymak ve formun submit edildiği yerde de verinin değiştirilmeden gönderildiğinden emin olmak için encryption ve hashing kullanılabilir.

PHP'nin MCRYPT eklentisi ile veriyi aşağıdaki şekilde şifreleyebiliriz:

--------------------
<?php
     $anahtar = md5("bol_sifreli_guvenli_veri");
     $gercek_deger = "1566";
     $iv = substr(md5("sifreli"), 0, mcrypt_get_iv_size(MCRYPT_BLOWFISH,
          MCRYPT_MODE_CFB));
     $sifreli_deger = base64_encode(mcrypt_encrypt(MCRYPT_BLOWFISH, $anahtar,
          $gercek_deger, MCRYPT_MODE_CFB, $iv));
     $tuz = substr(md5(uniqid(rand(), true)), 0, 10);
     $hashli_deger = $salt . substr(sha1($tuz . $gercek_deger),-10);
?>
<form action = "formu_isle.php" method = "post">
     <input type = "hidden" name = "sifreli_veri" value = "<?php echo $sifreli_deger; ?>" />
     <input type = "hidden" name = "hashli_veri" value = "<?php echo $hashli_deger; ?>" />
     <input type = "submit" value = "Formu Gönder" />
</form>
--------------------

formu_isle.php sayfasında da aşağıdaki işlemleri yaparak verimizi gerçek haline döndürebiliriz:

--------------------
<?php
if (!isset($_POST["sifreli_veri"]) || !isset($_POST["hashli_veri"])) {
     die("Veriler submit edilmemiş!");
} else {
     $anahtar = md5("bol_sifreli_guvenli_veri");
     $iv = substr(md5("sifreli"), 0, mcrypt_get_iv_size(MCRYPT_BLOWFISH,
          MCRYPT_MODE_CFB));
     $sifresi_cozulmus_deger = mcrypt_decrypt(MCRYPT_BLOWFISH, $anahtar
          base64_decode($_POST["sifreli_veri"]), MCRYPT_MODE_CFB, $iv);
     $tuz = substr($_POST["hashli_veri"], 0, 10);
     $yeni_hashli_deger = $salt . substr(sha1($tuz . $sifresi_cozulmus_deger), -10);
     if ($yeni_hashli_deger == $_POST["hashli_veri"]) {
          print $sifresi_cozulmus_deger; // yani bu örnekte "1566" değeri
     } else {
          print "Veri değiştirilmiş!";
     }
}
--------------------


MCRYPT eklentisini kullanmak istemiyor veya hash ile uğraşmak istemiyor olabilirsiniz. Örneğin bir combobox seçeneklerindeki değerlerin şifreli görünmesini istiyor olabilirsiniz.
İşte o zaman herhangi bir şifreleme algoritmasını (AES, Blowfish, vb.) kullanabilirsiniz.

Birçok şifreleme algoritmasını hazır halde buradaki "Download phpseclib" butonuna tıklayarak indirebilirsiniz. İndirdikten sonra aşağıdaki gibi bir php sayfası oluşturarak şifreleme ve şifreyi çözme fonksiyonları yazdıktan sonra istediğiniz zaman kullanabilirsiniz.

--------------------
<?php
include "/crypt/AES.php";

function sifrele($id) {
     $aes = new Crypt_AES();
     $aes->setKey('abcdefghijklmnop');
     $sifreli_deger = urlencode($aes->encrypt($id));
     return $sifreli_deger;
}

function sifreyi_coz($sifrelenmis_veri) {
     $aes = new Crypt_AES();
     $aes->setKey('abcdefghijklmnop');
     $sifrelenmis_veri = urldecode($sifrelenmis_veri);
     $sifresi_cozulmus_deger = $aes->decrypt($sifrelenmis_veri);
     return $sifresi_cozulmus_deger;
}
--------------------

Aşağıdaki gibi bir combobox içinde kullanabiliriz. Formun gönderildiği sayfada da sifreyi_coz() fonksiyonunu kullanarak gerçek veriye ulaşabiliriz.

--------------------
<select name = "cinsiyet" id = "cinsiyet">
     <option value = "-1">Seçiniz...</option>
     <?php
          echo "<option value = '" . sifrele(1) . "'>Kadın</option>";
          echo "<option value = '" . sifrele(2) . "'>Erkek</option>";
     ?>
</select>
--------------------

1 yorum: