Использование и обработка токенов 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/