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

实现PHP会话令牌时出现的问题,php,html,session,token,csrf-protection,Php,Html,Session,Token,Csrf Protection,我正在尝试对Web表单实施CSRF保护。它是一个单页的网站,可以捕获数据,将其发布到一个PHP文件中,然后通过电子邮件将信息发送给我。网页按预期运行(不包括安全性) 我有以下问题: 我不知道如何实现PHP代码来设置令牌;将index.html转换为index.php将加载一个空白正文。我认为解决这个问题可能会解决我的问题 当我尝试从jQuery调用token.php时,我得到一个403错误 当我尝试在1像素iframe中运行脚本时,我得到了一个500错误(我假设它是在HTML上运行的) toke

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

我有以下问题:

  • 我不知道如何实现PHP代码来设置令牌;将index.html转换为index.php将加载一个空白正文。我认为解决这个问题可能会解决我的问题
  • 当我尝试从jQuery调用token.php时,我得到一个403错误
  • 当我尝试在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";
    }
    ?>
    
    
    
    我在index.html中的jQuery尝试

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

    如果上面的PHP没有错误,我假设成功地将其转换为index.PHP将解决我的问题,但我很难做到这一点

    您的代码有一些问题:

    token.php
    需要输出令牌。这就像
    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
        });
    )};
    
    回答您的问题:

  • $\u会话['token']=bin2hex(随机字节(32))
    表示变量
    $\u SESSION['token']
    包含您的令牌。这就是你要设置的地方

  • 如果在ajax请求中请求
    token.php
    时出现403错误,这意味着服务器不会处理该请求。所以这可能是权限问题或其他问题。尝试将
    模具放入(“测试”)在脚本的第一行,然后在浏览器中执行
    /token.php
    。你能访问它吗,还是会给你一个错误?如果可以访问,则会显示“测试”。如果不确定无法访问服务器的原因,请查看服务器错误日志。根据代码,脚本的URL不太可能是错误的,或者会给您一个404错误

  • 现在还不清楚你为什么要烦恼:“当我尝试在1像素iframe中运行脚本时”。我假设这是试图将
    token.php
    的响应写回页面。这可以通过我上面的回答来解决


  • 您可以共享整个index.html文件内容吗?顺便说一句,您应该在token.php中回显token变量,否则该文件不会发出任何内容,ajax响应也没有内容。“将index.html转换为index.php将加载正文空白”通常意味着.php解析已终止(致命的不可恢复)。您的浏览器应该显示服务器500错误?检查服务器上的错误日志(如果启用了日志记录),问题是
    $.get('token.php')就不会对其进行任何处理。想必你是想把脚本的输出写回你的页面?@Alberto Boss不让我识别网站,所以我不能在不剥离大块内容的情况下发布索引。我是否需要将生成的令牌设置为隐藏字段,以便在formsubmit.php中进行比较?谢谢您的评论。当我在浏览器中导航到php文件时,我能够访问和运行php文件而不会出现问题。403和500错误似乎是由我的编码技能造成的。明天我将讨论代币问题,感谢您提供的修改。至于iFrame,我愚蠢地认为我可以让它在HTML中运行php。你可以让php脚本在iFrame中执行,但这不是实现你在这里尝试的任何事情的正确方法。如上所述,使用jquery将
    token.php
    的输出写回您的网页。这里根本不需要iFrame。