用于表单安全性的 PHP 会话令牌


PHP Session Tokens for form security

我无法在Chrome或Firefox中成功提交我正在处理的表单。但是,该表单在 Safari 中有效。

我上周刚开始尝试使用PHP,并修改了这篇关于CSS Tricks的文章中的代码。我正在尝试给会话一个随机令牌,将该令牌存储在变量中,将该令牌设置为隐藏的输入字段,然后在提交表单时确保两者匹配。

问题是创建的会话令牌与作为值分配给隐藏输入的令牌不匹配。提交表单时,将重新创建新的会话令牌,因此与会话中的原始随机数不匹配。奇怪的是,它可以在Safari中运行,而不是在其他浏览器中。

菲律宾比索

<?php 
session_start();
function generateFormToken($form) {
    // generate a token from an unique value, took from microtime, you can also use salt-values, other crypting methods...
    $token = md5(uniqid(microtime(), true));  
    // Write the generated token to the session variable to check it against the hidden field when the form is sent
    $_SESSION[$form.'_token'] = $token; 
    echo $token;
    return $token;
}
function verifyFormToken($form) {
    // check if a session is started and a token is transmitted, if not return an error
    if(!isset($_SESSION[$form.'_token'])) { 
        return false;
    }
    // check if the form is sent with token in it
    if(!isset($_POST['token'])) {
        return false;
    }
    // compare the tokens against each other if they are still the same
    if ($_SESSION[$form.'_token'] !== $_POST['token']) {
        return false;
    }
    return true;
}
function check_input($data)
{
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
  }
if (verifyFormToken('form1')) {
    $name = check_input($_POST["name"]);
    $email = check_input($_POST["emailaddress"]);
    $message = check_input($_POST["message"]);
    $ForwardTo = 'me@gmail.com';
    $details='Name: '.$name."'n".'Email: '.$email."'n".'Message: '.$message."'n";
        //do stuff
    mail($ForwardTo,"Construction of Hope Contact",$details,"From:$email");
}
?>

相关表格:

<!--Markup for Contact form-->
		<form action='index.php' method='post' class='contact-format'>
		<p><input type="hidden" name="token" value="<?php echo $newToken; ?>"></p>
		<p>
      <button type="submit" name='submit' class="btn btn-primary button">Send</button>
    </p>

我认为你所拥有的非常接近。我想我会改变几件事,但总的来说,我认为你所拥有的是接近的:

/

functions/validate.php

function fetchToken($form)
    {
        $token  =   md5(uniqid(microtime(), true));
        $_SESSION['token'][$form]   =   $token; 
        // Just return it, don't echo and return
        return $token;
    }
function matchToken($form)
    {
        if(!isset($_POST['token'][$form]))
            return false;
        // I would clear the token after matched
        if($_POST['token'][$form] === $_SESSION['token'][$form]) {
            $_SESSION['token'][$form]   =   NULL;
            return true;
        }
        // I would return false by default, not true
        return false;
    }

索引.php

// Include functions
include(__DIR__.'/functions/validate.php');
// Start session
session_start();
// match the token
if(matchToken('mailer')) {
    // do stuff
    echo true;
}
?>
<form action='index.php' method='post' class='contact-format'>
    <!-- You will echo here and also set the session variable here -->
    <!-- I would also use an array to contain my tokens, cleaner I think -->
    <input type="hidden" name="token[mailer]" value="<?php echo fetchToken('mailer'); ?>">
    <button type="submit" name='submit' class="btn btn-primary button">Send</button>
</form>

我的代码在 Safari 中似乎很好,但其他浏览器与令牌不匹配。

涉及的问题....没有网站图标。

这篇文章是解决问题的关键。