Проблемы при реализации токена сеанса PHP

Я пытаюсь реализовать защиту CSRF для веб-формы. Это одностраничный веб-сайт, который собирает данные, отправляет их в файл PHP, который затем отправляет мне информацию по электронной почте. Веб-страница функционирует должным образом (без обеспечения безопасности).

У меня следующие проблемы:

  1. Я не могу понять, как реализовать код PHP для установки токена; преобразование index.html в index.php загружает пустое тело. Я думаю, что решение этой проблемы, скорее всего, решит мои проблемы.
  2. Когда я пытаюсь вызвать token.php из jQuery, я получаю ошибку 403.
  3. Когда я пытаюсь запустить скрипт в iframe размером 1 пиксель, я получаю ошибку 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 решит мои проблемы, но у меня возникли трудности с этим.

Можете ли вы поделиться всем содержимым файла index.html?

Alberto 29.08.2018 17:44

Кстати, вы должны повторить переменную токена в token.php, иначе ничего не выйдет из этого файла и ответ ajax не будет иметь содержимого.

Alberto 29.08.2018 17:45

«преобразование index.html в index.php загружает пустой текст» обычно означает, что синтаксический анализ .php завершился неудачно (неустранимая ошибка). Ваш браузер должен показывать ошибку сервера 500? Проверьте журналы ошибок на вашем сервере (если у вас было включено ведение журнала).

IncredibleHat 29.08.2018 17:48

Проблема в том, что $.get('token.php'); ничего не делает с данными после того, как они были возвращены сервером. Предположительно вы хотите записать результат этого сценария обратно на свою страницу?

Andy 29.08.2018 17:50

@Alberto Boss не позволяет мне идентифицировать веб-сайт, поэтому я не могу опубликовать индекс, не удаляя из него большие куски. Нужно ли мне взять сгенерированный токен и установить его в скрытое поле, чтобы я мог сравнить его в formsubmit.php?

Niall 29.08.2018 18:07

@IncredibleHat Теперь они есть, я сообщу, как только поиграюсь.

Niall 29.08.2018 18:07

@Andy Это я просто пытался запустить скрипт. Я считаю, что мне нужно установить токен в качестве переменной для публикации с формой, чтобы я мог сравнить его на formsubmit.php. Это правильно?

Niall 29.08.2018 18:07

@Niall, я отправил ответ. Проверьте это и прокомментируйте, если он работает / не работает.

Andy 29.08.2018 18:08
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
8
207
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

С вашим кодом есть несколько проблем:

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
    });
)};

Чтобы ответить на ваши вопросы:

  1. $_SESSION['token'] = bin2hex(random_bytes(32)); означает, что переменная $_SESSION['token'] содержит ваш токен. Вот где вы его устанавливаете.

  2. Если вы получаете ошибку 403 при запросе token.php в запросе ajax, это означает, что сервер не будет обрабатывать этот запрос. Так что это может быть проблема с разрешениями или другая проблема. Попробуйте поместить die('test'); в первую строку скрипта, а затем запустить /token.php в своем браузере. Вы можете получить к нему доступ или выдает ошибку? Если он доступен, будет написано «тест». Проверьте журнал ошибок серверов, если вы не знаете, почему вы не можете получить к нему доступ. Судя по коду, маловероятно, что URL-адрес скрипта неправильный или это приведет к ошибке 404.

  3. Непонятно, почему вы возились с: «Когда я пытаюсь запустить скрипт в iframe размером 1 пиксель». Я предполагаю, что это попытка записать ответ token.php обратно на страницу. Это можно решить с помощью моего ответа выше.

Спасибо за ваши комментарии. Я могу без проблем получать доступ к php-файлам и запускать их, когда перехожу к ним в браузере. Ошибки 403 и 500, похоже, вызваны моими навыками программирования. Завтра я обращусь к проблеме с токенами, спасибо за внесенные вами поправки. Что касается iFrame, я был глуп, думая, что могу заставить его запускать php в HTML.

Niall 29.08.2018 18:23

Вы можете заставить PHP-скрипт выполняться внутри iframe, но это неправильный способ добиться того, что вы здесь пытаетесь сделать. Используйте jquery для записи вывода token.php обратно на вашу веб-страницу, как описано выше. Здесь нет необходимости в iframe.

Andy 30.08.2018 13:13

Другие вопросы по теме