实施 PHP 会话令牌时出现问题

Issues while implementing a PHP session token

我正在尝试对网络表单实施 CSRF 保护。它是一个捕获数据的单页网站,将其发布到 PHP 文件,然后通过电子邮件将信息发送给我。该网页按预期运行(减去安全性)。

我遇到了以下问题:

  1. 我不知道如何实现 PHP 代码来设置令牌;将 index.html 转换为 index.php 会加载空白正文。我认为解决这个问题可能会解决我的问题。
  2. 当我尝试从 jQuery 调用 token.php 时,出现 403 错误。
  3. 当我尝试 运行 1 像素 iframe 中的脚本时,出现 500 错误(我假设它在 HTML 上 运行)。

token.php

<?php
session_start();

if (empty($_SESSION['token'])) {
    $_SESSION['token'] = bin2hex(random_bytes(32));
}

$token = $_SESSION['token'];
?>

formsubmit.php

<?php 
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if (!empty($_POST['token'])) {
        if (hash_equals($_SESSION['token'], $_POST['token'])) {
            $emailbody = 'Name: ' . $_POST['m_title'] . ' ' . $_POST['m_firstname'] . ' ' . $_POST['m_surname'] . "\n"
                . 'Email: ' . $_POST['m_email'] . "\n"
                . 'Phone: ' . $_POST['m_phone'] . "\n"
                . 'D.O.B: ' . $_POST['m_dob_day'] . ' ' . $_POST['m_dob_month'] . ' ' . $_POST['m_dob_year'] . "\n"         
                . 'Postcode: ' . $_POST['m_postcode'] . "\n"
                . 'Lenders: ' . $_POST['m_bank1']  . ',' . $_POST['m_bank2'] . ',' . $_POST['m_bank3'] . ',' . $_POST['m_bank4'] . ',' . $_POST['m_bank5'] . ',' . $_POST['m_bank6'] . ',' . $_POST['m_bank7'] . ',' . $_POST['m_bank8'];               
            mail('**removed**', 'Web Lead', $emailbody);
            header('Location: **removed**/thankyou');
            exit();
        }   
        else {
            echo "token invalid";
        }
    }
    else {
        echo "token blank";
    }
}
else {
    echo "invalid request";
}
?>

我的 jQuery 尝试 index.html

<script>
$(document).ready(function() {
    $.get('token.php');
}); 
</script>

如果上面的 PHP 没有错误,我原以为成功将其转换为 index.php 会解决我的问题,但我很难这样做。

您的代码存在一些问题:

token.php需要输出token。这就像 echo $token;

一样简单

主要问题是您使用了以下 jquery:

$(document).ready(function() {
$.get('token.php');
});

这意味着当加载页面 (index.html) 时,您的浏览器向 token.php 发出 ajax 请求。然而……没有进一步的事情发生。您实际上并没有对 token.php.

的响应(输出)做任何事情

您需要做的是将 token.php 的回复放入您的网页。关闭您发布的代码我假设有一个名为 "token" 的表单字段?如果是这种情况,那么您将像这样发出 ajax 请求,它将 token.php 的响应写入该字段:

$(document).ready(function() {
    $.get('token.php').done(function(data) {
        $('input[name="token"]').val(data);
    }).fail() {
       // Handle ajax request failure here
    });
)};

回答您的问题:

  1. $_SESSION['token'] = bin2hex(random_bytes(32)); 表示变量 $_SESSION['token'] 包含您的令牌。那就是你要设置它的地方。

  2. 如果您在 ajax 请求中请求 token.php 时遇到 403 错误,这意味着服务器不会处理该请求。所以这可能是权限问题或其他问题。尝试将 die('test'); 放在脚本的第一行,然后在浏览器中执行 /token.php。你可以访问它,还是它给你一个错误?如果可以访问,它会显示 "test"。如果您不确定为什么无法访问它,请检查服务器错误日志。根据代码,脚本的 URL 不太可能是错误的,否则会给您带来 404 错误。

  3. 不清楚您为何烦恼:"When I try and run the script in a 1-pixel iframe"。我假设这是将 token.php 的响应写回页面的尝试。这可以通过我上面的回答来解决。