【问题标题】:$_SESSION[''token] never matching $_POST['token']$_SESSION[''token] 从不匹配 $_POST['token']
【发布时间】:2014-12-19 20:08:28
【问题描述】:

我正在构建一个表单并保护它免受 CSRF 等攻击。

session_start();
mb_internal_encoding('UTF-8');
$_SESSION['token'] = null;

//other code to check and control form

function create_token() {
    $token = md5(uniqid(mt_rand(), true));

    $_SESSION['token'] = $token;

    return $token;
}

$newToken = create_token();

然后在我的表格中输入<input name=:"token" type="hidden" value="<?php echo ($newToken);?>">

现在,如果我想通过这样做来验证表单提交:

function user_submit_check() {
    if(!isset($_SESSION['token'])) { 
        return false;
    }

    if(!isset($_POST['token'])) {
        return false;
    }
    //This next 'if' statement always returns false
    if ($_POST['token'] !== $_SESSION['token']) {
        return false;
    }
return true;
}

if (user_submit_token() === true) {
    //process user input
} else {
    die("There is a problem with verification.");
}

问题是user_submit_check() 总是返回false,(见函数注释)。到目前为止,我找不到任何关于为什么会发生这种情况的解决方案。许多消息来源表明这种方法有效。

我也尝试使用echo ("posted input token" . $_POST['token'] . "stored in $_SESSION" . $_SESSION['token']);手动检查$_POST['token'] !== $_SESSION['token']

这表明这两个令牌实际上是相同的,至少在纸面上是这样。 我可能遗漏了一些东西,但我对用 PHP 保护表单有点陌生。

编辑: 也许分享有用,我目前在一页上做所有的安全和所有 html/form 的东西。我使用这个:<form action="<?php $_SERVER['PHP_SELF'];?>" 来执行脚本...(检查空表单字段等)。

编辑 2: 感谢@CBroe,指出所有属性上没有“”的坏 HTML。

有人知道我做错了吗?

【问题讨论】:

  • “这表明这两个标记实际上是相同的,至少在纸面上是” – 使用 var_dump 分别输出这两个值,而不是通过连接它们首先变成一个字符串。结果是什么? (请通过复制和粘贴显示准确结果。)
  • 会的,结果很快就出来了。谢谢
  • 检查两者的数据类型
  • 谢谢@CBroe,你救了我!它们实际上彼此不同..首先要解决这个问题..我会在修复后更新帖子。感谢您的帮助

标签: php forms function session post


【解决方案1】:

检查项目是否已在第 1 次发布。

<?php

if($_SERVER['REQUEST_METHOD'] === 'POST') 
{    
    if(isset($_POST['token'])) 
    {       
        // Test to see if tokens match
        if($_SESSION['token'] === $_POST['token']) 
        {           
            // process user input
            unset($_SESSION['token']);
        } else {
            die('Tokens did not match');
        }
    } else {
        die('No token found');
    }
} else {

    $_SESSION['token'] = md5(uniqid(mt_rand(), true));

    ?>

<form>
<input name=token type=hidden value="<?php echo $_SESSION['token']; ?>">
</form>

<?php 
}
?>

【讨论】:

    【解决方案2】:

    您应该在回显之前检查会话是否已设置

    <input name="token" type=hidden 
           value=<?php echo (isset($_SESSION['token'])) ? $_SESSION['token'] : ''?>>
    

    PHP 代码对于您想要实现的目标应该非常简单:

    session_start();
    mb_internal_encoding('UTF-8');
    if(isset($_POST['submit'], $_POST['token'], $_SESSION['token'])){
    
        if ($_POST['token'] === $_SESSION['token']){
            echo 'token match';
        }else{
            echo 'token do not match';
        }
    
    }else{
        $_SESSION['token'] = md5(uniqid(mt_rand(), true));
    }
    

    【讨论】:

      猜你喜欢
      • 2016-10-09
      • 2015-08-25
      • 1970-01-01
      • 2021-04-07
      • 2015-07-27
      • 1970-01-01
      • 2020-07-06
      • 2016-04-19
      • 2018-01-18
      相关资源
      最近更新 更多