【发布时间】:2010-07-06 01:48:49
【问题描述】:
我使用这个类(取自博客教程)来生成唯一键来验证表单:
class formKey {
//Here we store the generated form key
private $formKey;
//Here we store the old form key
private $old_formKey;
//The constructor stores the form key (if one excists) in our class variable
function __construct() {
//We need the previous key so we store it
if(isset($_SESSION['form_key'])) {
$this->old_formKey = $_SESSION['form_key'];
}
}
//Function to generate the form key
private function generateKey() {
//Get the IP-address of the user
$ip = $_SERVER['REMOTE_ADDR'];
//We use mt_rand() instead of rand() because it is better for generating random numbers.
//We use 'true' to get a longer string.
$uniqid = uniqid(mt_rand(), true);
//Return the hash
return md5($ip . $uniqid);
}
//Function to output the form key
public function outputKey() {
//Generate the key and store it inside the class
$this->formKey = $this->generateKey();
//Store the form key in the session
$_SESSION['form_key'] = $this->formKey;
//Output the form key
// echo "<input type='hidden' name='form_key' id='form_key' value='".$this->formKey."' />";
return $this->formKey;
}
//Function that validated the form key POST data
public function validate() {
//We use the old formKey and not the new generated version
if($_POST['form_key'] == $this->old_formKey) {
//The key is valid, return true.
return true;
}
else {
//The key is invalid, return false.
return false;
}
}
}
我网站上的所有东西都先通过 index.php,所以我把这个放在 index.php 中:$formKey = new formKey();
然后,在每一种形式中,我都会这样写:<?php $formKey->outputKey(); ?>
生成这个:<input type="hidden" name="form_key" id="form_key" value="7bd8496ea1518e1850c24cf2de8ded23" />
然后我可以简单地检查if(!isset($_POST['form_key']) || !$formKey->validate())
我有两个问题。第一:我每页不能使用多个表单,因为只有最后一个生成的密钥才会生效。
第二:因为一切都先通过 index.php,如果我使用 ajax 验证表单,第一次会验证但第二次不会,因为 index.php 生成一个新键,但包含表单的页面会' t 刷新所以表单键不更新..
我已经尝试了几件事,但我无法让它工作。也许你可以更新/修改代码/类来让它工作??谢谢!!!
【问题讨论】:
-
为什么需要这个验证?您对垃圾邮件提交有疑问吗?
-
针对 XSS(跨站点脚本)和表单上的跨站点请求伪造提供一些安全性。
-
我在这段代码中看不到任何针对 xss 的保护措施。 xsrf 和 xss 是非常不同的攻击。