实现PHP会话令牌时出现的问题
我正在尝试对Web表单实施CSRF保护。它是一个单页的网站,可以捕获数据,将其发布到一个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
<?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')一旦数据被服务器返回,code>就不会对其进行任何处理。想必你是想把脚本的输出写回你的页面?@Alberto Boss不让我识别网站,所以我不能在不剥离大块内容的情况下发布索引。我是否需要将生成的令牌设置为隐藏字段,以便在formsubmit.php中进行比较?谢谢您的评论。当我在浏览器中导航到php文件时,我能够访问和运行php文件而不会出现问题。403和500错误似乎是由我的编码技能造成的。明天我将讨论代币问题,感谢您提供的修改。至于iFrame,我愚蠢地认为我可以让它在HTML中运行php。你可以让php脚本在iFrame中执行,但这不是实现你在这里尝试的任何事情的正确方法。如上所述,使用jquery将token.php
的输出写回您的网页。这里根本不需要iFrame。