Использование и обработка токенов PHP-форм
Я начинаю работать с логином script в PHP. Это выражение маркера формы, которое у меня есть до сих пор:
$_SESSION["form_token"] = md5(rand(time (), true)) ;
Заявление выдается сразу после того, как пользователь указывает, что он/она хочет войти в систему.
Мое ограниченное понимание заключается в том, что цель токенов состоит в том, чтобы идентифицировать уникального пользователя в уникальный момент времени и замаскировать информацию о токенах формы.
Тогда все становится нечетким. Вот мои 3 открытых вопроса:
-
Когда самое лучшее время для проверки маркера формы для целей безопасности?
-
Как это проверить?
-
Когда, если когда-либо, я "уничтожаю" токен формы? (IOW, будет ли токен формы оставаться активным до тех пор, пока пользователь не выйдет из системы?
Ответы
Ответ 1
Нет необходимости делать то, что вы пытаетесь сделать. Когда вы начинаете сеанс в PHP с помощью session_start(), для вас уже создан уникальный SESSIONID. Вы не должны помещать это в форму. По умолчанию он обрабатывается через файлы cookie. Также нет необходимости проверять SESSIONID, который снова обрабатывается для вас.
Вы отвечаете за аутентификацию пользователя и сохранение их аутентифицированного удостоверения (например, $_SESSION ['user_id'] = $userId на СЕССИИ. Если пользователь выходит из системы, вы уничтожаете их сессию с помощью session_destroy.
Вы должны убедиться, что session_start() является одной из первых вещей для всех страниц вашего сайта.
Вот пример:
<?php
session_start(); // starts new or resumes existing session
session_regenerate_id(true); // regenerates SESSIONID to prevent hijacking
function login($username, $password)
{
$user = new User();
if ($user->login($username, $password)) {
$_SESSION['user_id'] = $user->getId();
return true;
}
return false;
}
function logout()
{
session_destroy();
}
function isLoggedIn()
{
return isset($_SESSION['user_id']);
}
function generateFormHash($salt)
{
$hash = md5(mt_rand(1,1000000) . $salt);
$_SESSION['csrf_hash'] = $hash
return $hash;
}
function isValidFormHash($hash)
{
return $_SESSION['csrf_hash'] === $hash;
}
Изменить: я неправильно понял исходный вопрос. Я добавил соответствующие методы для генерации и проверки хэшей форм;
Пожалуйста, просмотрите следующие ресурсы:
Ответ 2
это предотвращает атаки CSRF
http://en.wikipedia.org/wiki/Cross-site_request_forgery
злоумышленник может теоретически отобразить форму, которая помещается в ваше приложение. форма может содержать инструкции, которые вызывают нарушение данных или какое-либо нежелательное действие. пользователь может быть обманут в отправке формы, которую приложение будет принимать, потому что пользователь уже зарегистрировался. Значок формы гарантирует, что форма была создана вашим сайтом, а не каким-либо другим сайтом.
проверка HTTP_REFERER часто достаточно хороша, но не как полное решение (например, https не отправит строку referrer).
если вы действительно хотите защитить все формы с помощью токена, вы можете создать некоторые удобные функции, такие как emitToken() и checkToken(), которые сделают его доступным для всего сайта.
несколько примеров:
http://phpsec.org/projects/guide/2.html
http://www.rodsdot.com/php/CSRF_Form_Protection.php
Ответ 3
Вы можете проверить реализацию фреймворка zend.
Помимо конкретной реализации, документы описывают рассуждения и использование этого типа элемента в форме.
Свой Zend_Form_Element_Hash
https://docs.zendframework.com/zend-form/element/csrf/