Я пытаюсь реализовать защиту CSRF для веб-формы. Это одностраничный веб-сайт, который собирает данные, отправляет их в файл PHP, который затем отправляет мне информацию по электронной почте. Веб-страница функционирует должным образом (без обеспечения безопасности).
У меня следующие проблемы:
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, иначе ничего не выйдет из этого файла и ответ ajax не будет иметь содержимого.
«преобразование index.html в index.php загружает пустой текст» обычно означает, что синтаксический анализ .php завершился неудачно (неустранимая ошибка). Ваш браузер должен показывать ошибку сервера 500? Проверьте журналы ошибок на вашем сервере (если у вас было включено ведение журнала).
Проблема в том, что $.get('token.php'); ничего не делает с данными после того, как они были возвращены сервером. Предположительно вы хотите записать результат этого сценария обратно на свою страницу?
@Alberto Boss не позволяет мне идентифицировать веб-сайт, поэтому я не могу опубликовать индекс, не удаляя из него большие куски. Нужно ли мне взять сгенерированный токен и установить его в скрытое поле, чтобы я мог сравнить его в formsubmit.php?
@IncredibleHat Теперь они есть, я сообщу, как только поиграюсь.
@Andy Это я просто пытался запустить скрипт. Я считаю, что мне нужно установить токен в качестве переменной для публикации с формой, чтобы я мог сравнить его на formsubmit.php. Это правильно?
@Niall, я отправил ответ. Проверьте это и прокомментируйте, если он работает / не работает.






С вашим кодом есть несколько проблем:
token.php необходимо вывести токен. Это так же просто, как echo $token;
Основная проблема в том, что вы использовали следующий jquery:
$(document).ready(function() {
$.get('token.php');
});
Это означает, что когда страница (index.html) загружается, ваш браузер делает запрос ajax к token.php. Однако ... дальше ничего не происходит. На самом деле вы ничего не делаете с ответом (выводом) от 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'] содержит ваш токен. Вот где вы его устанавливаете.
Если вы получаете ошибку 403 при запросе token.php в запросе ajax, это означает, что сервер не будет обрабатывать этот запрос. Так что это может быть проблема с разрешениями или другая проблема. Попробуйте поместить die('test'); в первую строку скрипта, а затем запустить /token.php в своем браузере. Вы можете получить к нему доступ или выдает ошибку? Если он доступен, будет написано «тест». Проверьте журнал ошибок серверов, если вы не знаете, почему вы не можете получить к нему доступ. Судя по коду, маловероятно, что URL-адрес скрипта неправильный или это приведет к ошибке 404.
Непонятно, почему вы возились с: «Когда я пытаюсь запустить скрипт в iframe размером 1 пиксель». Я предполагаю, что это попытка записать ответ token.php обратно на страницу. Это можно решить с помощью моего ответа выше.
Спасибо за ваши комментарии. Я могу без проблем получать доступ к php-файлам и запускать их, когда перехожу к ним в браузере. Ошибки 403 и 500, похоже, вызваны моими навыками программирования. Завтра я обращусь к проблеме с токенами, спасибо за внесенные вами поправки. Что касается iFrame, я был глуп, думая, что могу заставить его запускать php в HTML.
Вы можете заставить PHP-скрипт выполняться внутри iframe, но это неправильный способ добиться того, что вы здесь пытаетесь сделать. Используйте jquery для записи вывода token.php обратно на вашу веб-страницу, как описано выше. Здесь нет необходимости в iframe.
Можете ли вы поделиться всем содержимым файла index.html?