【发布时间】:2014-09-23 04:03:50
【问题描述】:
我正在尝试通过在每个表单上生成一个唯一令牌来保护我的表单免受 CSRF 攻击。我的表单上有一个隐藏字段,它会生成一个独特的令牌,如下所示:
public static function generateToken() {
return $_SESSION['token'] = md5(uniqid(mt_rand(), TRUE));
}
我知道 md5 已贬值,不应该使用,因为它不像以下那样随机:
base64_encode(openssl_random_psuedo_bytes(32));
但我目前没有安装 ssl,我会处理这个问题。但我的主要问题是,在生成此令牌后,它会存储到用户当前所在的会话中,如下所示:
$_SESSION['token'] = $_POST['token'];
它获取包含生成令牌的字段的值。现在我已将此令牌存储到会话中,我需要弄清楚将其发送到处理文件。我在这个表单上有很多字段,所以在一个 if() 语句中检查每一件事看起来有点奇怪。我想我想说的是,如何在处理数据的表单上检查此令牌,如果令牌与表单上生成的令牌不同,我可以拒绝该数据吗?直接用die()杀掉处理脚本?
我也想知道我是否需要这样做 - 我已经阅读了 CSRF,但我想有人能做的最糟糕的事情就是更改一些正在发送以进行处理的信息,这就是为什么我要想要传递令牌来检查和拒绝数据就是这种情况。
<form name="form1" action="processing.php" method="POST" enctype="multipart/form-data">
这就是我所说的其他文件。 PHP 不是全部在一个地方,我通过 $_POST 方法获取处理脚本上的所有内容。
【问题讨论】:
-
我们需要生成一个令牌将其存储在会话中,并且还需要在表单中有一个具有相同值的字段,例如通过回显它。当表单被提交回来时,我们需要检查/比较我们在会话中保存的值,以验证我们呈现的表单仅被提交,而不是来自不同站点的一些随机表单被提交到我们的站点。