Использование и обработка токена формы PHP - PullRequest
17 голосов
/ 09 января 2010

Я новичок, работающий над сценарием входа в PHP. Это утверждение токена формы, которое у меня есть до сих пор:

$_SESSION["form_token"] = md5(rand(time (), true)) ;

Выписка выдается сразу после того, как пользователь указывает, что хочет войти в систему.

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

Тогда все становится нечетким. Вот мои 3 открытых вопроса:

  1. Когда лучше всего «проверять» токен формы в целях безопасности?

  2. Как мне это проверить?

  3. Когда, если вообще, я "уничтожу" жетон формы? (IOW, будет ли маркер формы оставаться "активным", пока пользователь не выйдет из системы?

Ответы [ 3 ]

19 голосов
/ 09 января 2010

это для предотвращения CSRF-атак

http://en.wikipedia.org/wiki/Cross-site_request_forgery

вредоносный сайт теоретически может отображать форму, которая публикуется в вашем приложении. форма может содержать инструкции, которые вызывают нарушение данных или некоторые нежелательные действия. пользователь может быть обманут в отправке формы, которую примет приложение, потому что пользователь уже вошел в систему. Маркер формы гарантирует, что форма была создана вашим сайтом, а не каким-либо другим сайтом.

проверка HTTP_REFERER часто достаточно хороша, но не является полным решением (например, https не отправит строку-реферер).

Если вы действительно хотите защитить все формы токеном, вы можете создать несколько удобных функций, таких как emitToken () и checkToken (), которые позволят ему работать на всем сайте.

некоторые примеры:

http://phpsec.org/projects/guide/2.html

http://www.rodsdot.com/php/CSRF_Form_Protection.php

13 голосов
/ 09 января 2010

Нет необходимости делать то, что вы пытаетесь. Когда вы начинаете сеанс в PHP с помощью session_start (), для вас уже генерируется уникальный SESSIONID. Вы должны не указывать это в форме. По умолчанию он обрабатывается через куки. Также нет необходимости проверять SESSIONID, который снова обрабатывается для вас.

Вы несете ответственность за аутентификацию пользователя и сохранение его аутентифицированной личности (например, $ _SESSION ['user_id'] = $ userId в SESSION. Если пользователь выходит из системы, вы уничтожаете его сеанс с помощью 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;
}

Редактировать: я неправильно понял исходный вопрос. Я добавил соответствующие методы выше для генерации и проверки хэшей форм;

Пожалуйста, смотрите следующие ресурсы:

0 голосов
/ 09 января 2010

Вы можете проверить реализацию Zend Framework.

Помимо конкретной реализации, документы описывают обоснование и использование элементов такого типа в форме.

Это Zend_Form_Element_Hash https://docs.zendframework.com/zend-form/element/csrf/

...