防止欺骗形式

时间:2012-11-29 18:40:33

标签: php security

我有一个提交表单的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>

idsecret都不会返回相同的值 这是为什么?我错过了什么?


更新

所以,我在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的帖子。 现在效果很好谢谢。

3 个答案:

答案 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

只要您在脚本开头检查匹配(生成下一个秘密之前),就可以了。