实施 PHP 会话令牌时出现问题
Issues while implementing a PHP session token
我正在尝试对网络表单实施 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";
}
?>
我的 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
});
)};
回答您的问题:
$_SESSION['token'] = bin2hex(random_bytes(32));
表示变量 $_SESSION['token']
包含您的令牌。那就是你要设置它的地方。
如果您在 ajax 请求中请求 token.php
时遇到 403 错误,这意味着服务器不会处理该请求。所以这可能是权限问题或其他问题。尝试将 die('test');
放在脚本的第一行,然后在浏览器中执行 /token.php
。你可以访问它,还是它给你一个错误?如果可以访问,它会显示 "test"。如果您不确定为什么无法访问它,请检查服务器错误日志。根据代码,脚本的 URL 不太可能是错误的,否则会给您带来 404 错误。
不清楚您为何烦恼:"When I try and run the script in a 1-pixel iframe"。我假设这是将 token.php
的响应写回页面的尝试。这可以通过我上面的回答来解决。
我正在尝试对网络表单实施 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";
}
?>
我的 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
});
)};
回答您的问题:
$_SESSION['token'] = bin2hex(random_bytes(32));
表示变量$_SESSION['token']
包含您的令牌。那就是你要设置它的地方。如果您在 ajax 请求中请求
token.php
时遇到 403 错误,这意味着服务器不会处理该请求。所以这可能是权限问题或其他问题。尝试将die('test');
放在脚本的第一行,然后在浏览器中执行/token.php
。你可以访问它,还是它给你一个错误?如果可以访问,它会显示 "test"。如果您不确定为什么无法访问它,请检查服务器错误日志。根据代码,脚本的 URL 不太可能是错误的,否则会给您带来 404 错误。不清楚您为何烦恼:"When I try and run the script in a 1-pixel iframe"。我假设这是将
token.php
的响应写回页面的尝试。这可以通过我上面的回答来解决。