CSRF для внутренней формы $ _SERVER [& quot; REQUEST_METHOD & quot;]

Попытка реализовать токен CSRF впервые …

У меня есть внутренний $_SERVER["REQUEST_METHOD"] форма …

Большая часть материала онлайн говорит о том, что это сделано через _$POST php форма …

Итак … прочитав все это, я пришел к выводу, что, поскольку он у меня есть, как во внутренней части, я должен установить токен там …

Так что это то, что я сделал … но, очевидно, я здесь что-то неправильно понимаю, потому что это не работает … не просто неправильно … Я также не уверен, что я должен делать … так что … если бы вы могли объяснить, что я должен делать, я могу установить это правильно … Я был бы очень признателен

<?php
session_start(); //allows use of session variables

$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();


if ($_SERVER["REQUEST_METHOD"] == "POST") {

if (empty($_POST["first-name"])) {
$firstNameErr = "First name is required";
} else {
$first_name = test_input($_POST["first-name"]);
}

if (empty($_POST["last-name"])) {
$lastNameErr = "Last name is required";
} else {
$last_name = test_input($_POST["last-name"]);
}

if (empty($_POST["email"])) {
$emailErr = "Email is required";
} else {
$email = test_input($_POST["email"]);
}

if (empty($_POST["message"])) {
$messageErr = "Message is required";
} else {
$message = test_input($_POST["message"]);
}


if(isset($first_name) && isset($last_name) && isset($email) && isset($message) && isset($token))
{
$_SESSION['first_name'] = $first_name;
$_SESSION['last_name'] = $last_name;
$_SESSION['email'] = $email;
$_SESSION['message'] = $message;
$_SESSION['token'] = $token;
header("Location: SessionsCRSF.php");
}
}

function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>

На этой же странице находится форма (разместив фрагмент, но вы поняли):

<form class="ui form"  method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

<input type="hidden" name="token" value="<?php echo $token; ?>" />

<div class="field">
<label>First Name</label>
<input name="first-name" id="first-name" placeholder="First Name" type="text" value="<?php if(isset($first_name)) { echo $first_name; }?>">
<?php if(isset($firstNameErr)) print ('<span class="error">* ' . $firstNameErr . '</span>'); ?>
</div>

(...)

</form>

Но я не знаю, как проверить это с помощью SessionsCRSF.php Форма, которую вы видите в списке в шапке …

Вот фрагмент SessionsCRSF.php форма, так как остальное это просто PHPMailer вещи:

<?php

session_start();

if ($_POST['token'] == $_SESSION['token'])
{
die('working, yay?');
}


$first_name = $_SESSION['first-name'];
$last_name = $_SESSION['last-name'];
$email = $_SESSION['email'];
$message = nl2br($_SESSION['message']);

require 'PHPMailerAutoload.php';

$mail = new PHPMailer;

РЕДАКТИРОВАНИЕ

Хорошо, так .. это то, что у меня так далеко, что работает:

<?php
session_start(); //allows use of session variables

if ($_SERVER["REQUEST_METHOD"] == "POST" && $_SESSION['token'] == $_POST['token'] && !empty($_SESSION['token'])) {

if (empty($_POST["first-name"])) {
$firstNameErr = "First name is required";
} else {
$first_name = test_input($_POST["first-name"]);
}

if (empty($_POST["last-name"])) {
$lastNameErr = "Last name is required";
} else {
$last_name = test_input($_POST["last-name"]);
}

if (empty($_POST["email"])) {
$emailErr = "Email is required";
} else {
$email = test_input($_POST["email"]);
}

if (empty($_POST["message"])) {
$messageErr = "Message is required";
} else {
$message = test_input($_POST["message"]);
}

if(isset($first_name) && isset($last_name) && isset($email) && isset($message))
{
$_SESSION['first_name'] = $first_name;
$_SESSION['last_name'] = $last_name;
$_SESSION['email'] = $email;
$_SESSION['message'] = $message;
header("Location: contact9SessionsCRSF2.php");
exit;
}
}
else {
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();
}

function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>

0

Решение

У вас есть ваша страница, которая содержит ваши $_SESSION значение, и у вас есть значение INPUT в скрытом поле в HTML-форме, которые совпадают с этим значением.

Page 1:
[SESSION] ... [INPUT]

Затем вы отправляете форму по адресу назначения, здесь, на странице 2, и затем проверяете, что значение отправленного вами скрытого поля равно $_SESSION значение, которое не передается полем формы ввода.

Это входное значение находится из $_POST массив.

Page 2:
[SESSION] ... [POST]

Что касается вашей проблемы, вы отправляете свою форму на PHP_SELF страница (как правило, PHP_SELF является плохой переменной для использования, и это не поощряется), то есть на той же странице. НО, ваша проверка данных делается на sessionCRSF.php страница, так что вы должны обновить форму, чтобы поместить:

<form action='sessionCRSF.php' ... >

И затем в верхней части этой страницы ваша проверка значения токена должна пройти успешно.


Вы, кажется, демонстрируете некоторую путаницу относительно методов запроса SERVER, есть GET / POST / PUT и другие, и если у вас есть

У меня есть внутренняя форма $ _SERVER [«REQUEST_METHOD»]

что на самом деле это? Если это форма, то это метод GET / POST, и, насколько я знаю, он не внутренний, даже если он находится на одном и том же сервере, он перемещается с одной страницы на другую, поэтому применимы приведенные выше концепции.

Из обсуждения и разъяснения теперь я вижу решение:

в If операторы, которые обрабатывают отправку формы, вы не обрабатываете отправленное значение токена, $_POST['token'], Таким образом, вам нужно добавить оператор для обработки, в его самой простой форме, в точке кода, где вы устанавливаете значения для $_SESSION сформировать данные, добавить строку:

$_SESSION['posted_token'] = $_POST['token'];

Это все, что вам нужно, то в sessionCRSF.php вы сравниваете эти два значения, чтобы затем получить:

 if ($_SESSION['posted_token'] == $_SESSION['token'])
{
die('working, yay?');
}

(Вы меня раньше путали со ссылкой на «внутренние» формы и т. Д.!)

Вам нужно установить оригинал $_SESSION['token'] когда форма генерируется, НЕ когда форма отправлена, ваш код в настоящее время создает $_SESSION['token'] значение на каждой итерации, и поскольку страница ссылается на себя, это означает, что значения токенов, будучи случайными, никогда не будут одинаковыми. Вам нужно установить

if (form submitted){
save submitted POSTED token
}
else{
/// form not submitted
generate a token and save to session
}

Не делайте обе эти вещи на одной и той же итерации !!

Потому что иногда это проще увидеть …

Код был обновлен, чтобы сравнить токены при отправке POST и, следовательно, обойти всю необходимость отправки данных на другую страницу для сравнения.

<?php
session_start(); //allows use of session variables


if ($_SERVER["REQUEST_METHOD"] == "POST" &&
$_SESSION['token'] == $_POST['token'] && !empty($_SESSION['token'])) {

if (empty($_POST["first-name"])) {
$firstNameErr = "First name is required";
} else {
$first_name = test_input($_POST["first-name"]);
}

...etc...

if(isset($first_name) && isset($last_name) && isset($email) && isset($message))
{
$_SESSION['first_name'] = $first_name;
$_SESSION['last_name'] = $last_name;
$_SESSION['email'] = $email;
$_SESSION['message'] = $message;

header("Location: SessionsCRSF.php");
exit; //ALWAYS end execution after sending location headers.
}
}
else {
$token = md5(uniqid(rand(), TRUE));
$_SESSION['token'] = $token;
$_SESSION['token_time'] = time();
}
1

Другие решения

Других решений пока нет …