CSRF代码不起作用

时间:2014-09-20 16:34:31

标签: php csrf

我正在阅读Chris Shifflet撰写的一本书“Essential PHP Security”。有一章关于CSRF,作者建议使用令牌来防止CSRF。书中的代码表示要在我们使用的表单中添加令牌

<?php

session_start();
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();

?>

<form action="buy.php" method="POST">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
<p>
Item:
<select name="item">
    <option name="pen">pen</option>
    <option name="pencil">pencil</option>
</select><br />
Quantity: <input type="text" name="quantity" /><br />
<input type="submit" value="Buy" />
</p>
</form>

可以使用简单的条件语句检查令牌。

<?php

if (isset($_SESSION['token']) && $_POST['token']== $_SESSION['token'])
    {
        echo $_POST['token'];
        echo "form passed";
    }

但上面的代码似乎不起作用。 “表单已通过”消息未显示。上面的代码有什么问题?第一组代码生成令牌,但没有成功消息。

2 个答案:

答案 0 :(得分:0)

您需要在session_start();中添加buy.php代码的顶部。实施例...

session_start();
if (isset($_SESSION['token']) && $_POST['token']== $_SESSION['token'])
{
    echo $_POST['token'];
    echo "form passed";
}

答案 1 :(得分:0)

我建议你以功能有效的方式做到这一点:

session_start();
 function generate_token(){
    $token = uniqid(rand(), true);
    $_SESSION['token'] = $token;
    $_SESSION['token_time'] = time();
 }


 //avoid putting script at bottom until required
if($_SERVER['REQUEST_METHOD']=='POST' && !empty($_POST)){
if(isset($_SESSION['token']) && isset($_SESSION['token_time']) && 
 isset($_POST['token']))
  {

 if($_SESSION['token'] == $_POST['token'])
 {

    $timestamp_ancien = time() - (15*60);
    //Si le jeton n'est pas expiré
    if($_SESSION['token_time'] >= $timestamp_ancien)
    {
        //here Instruction  
        generate_token();//for next call


     }else{echo"error3";}
    }else{echo"error2";}
    }else{echo"error1";}
}
generate_token();

原因:您可以将该功能放在项目中的任何常用位置,并包含或要求该文件使用此代码,而无需在每个地方编写代码。