我有一个提交表单的php页面。
我想添加一张支票,我可以阻止基本的跨站点伪造。
我的代码:
<?php
session_start();
(...) //some code
$secret = substr(md5(uniqid(rand(), true)), 1, 2);
$_SESSION["secret"] = $secret;
$auth = $secret;
?>
(...)
<form id="form" name="form" action="<?php echo htmlentities($_SERVER[PHP_SELF]); ?>" method="post">
(...)
<input type="hidden" name="id" value="<? echo $auth; ?>" />
(...)
<?php
(...)
//as a debug I just tried to display
echo $_POST["id"];
echo "=";
echo $_SESSION["secret"];
(...)
?>
<div>
</body>
</html>
但id
和secret
都不会返回相同的值
这是为什么?我错过了什么?
更新
所以,我在Samuel Cook尝试了答案,Jon Stirling的评论也提出了这个答案:
if(!isset($_SESSION["secret"])){
$secret = substr(md5(uniqid(rand(), true)), 1, 2);
$_SESSION["secret"] = $secret;
$auth = $secret;
}
但现在如果没有$_SESSION["secret"]
页面返回:
<input type="hidden" name="id" value="" />
我理解为什么,因为只有会话变量存在才会设置秘密 有什么建议吗?
更新
在生成新的会话密钥之前移动了支票,并且只检查是否有一个id的帖子。 现在效果很好谢谢。
答案 0 :(得分:0)
一旦你打开一个页面$ auth将生成并且我将在提交$ _SESSION [“secret”]之后将进入隐藏字段,因为$ secret将生成新密钥但$ _POST ['id']是旧的即将到来来自Post方法。
答案 1 :(得分:0)
你总是在生成一个新的$secret
,因此它总会有所不同。您可以检查$_SESSION['secret']
是否存在,如果不存在则创建新变量。类似的东西:
if(!isset($_SESSION["secret"])){
$secret = substr(md5(uniqid(rand(), true)), 1, 2);
$_SESSION["secret"] = $secret;
$auth = $secret;
}
答案 2 :(得分:0)
在调试代码执行时,秘密已更改:
echo $_POST["id"]; // previous secret
echo "=";
echo $_SESSION["secret"]; // new secret
只要您在脚本开头检查匹配(生成下一个秘密之前),就可以了。