PHP сессии достаточно для авторизации пользователя? - PullRequest
4 голосов
/ 12 ноября 2010

Сценарий:

  • После того, как пользователь вошел в систему, устанавливается переменная сеанса, подтверждающая его вход в систему.
  • В верхней части каждой страницы переменная сеанса входа подтверждается действительной
  • Если это не так, они загружаются.
  • Постоянные файлы cookie не используются, только session

Вопрос:

Этодостаточно строгая мера безопасности, или я должен

  • установить две переменные сеанса для проверки друг друга и / или
  • реализовать проверку базы данных / хэша
  • ...?

========

(Кстати, пока я изучал этот вопрос, эта вики - фантастическое чтение.)

Ответы [ 5 ]

6 голосов
/ 12 ноября 2010

Достаточно сохранить только логин (или идентификатор пользователя) в сеансе.

Чтобы предотвратить фиксацию / перехват всего сеанса, нужно просто реализовать простой алгоритм (псевдокод):

if (!isset($_SESSION['hash']) {
    $_SESSION['hash'] = md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua');
} else if ($_SESSION['hash'] != md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua')) {
    session_regenerate_id();
    $_SESSION = array();
    $_SESSION['hash'] = md5(!empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua');
}

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

Вот как я реализовал такую ​​защиту в классе сеанса кохана:

abstract class Session extends Kohana_Session
{
    public function read($id = null)
    {
        parent::read($id);

        $hash = $this->calculateHash();
        $sessionHash = $this->get('session_fixation');

        if (!$sessionHash) {
            $this->set('session_fixation', $hash);
        } elseif ($sessionHash != $hash) {
            $this->regenerate();
            $_SESSION = array();
            $this->set('session_fixation', $hash);
        }
    }

    private function calculateHash()
    {
        $ip = !empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '127.0.0.1';
        $ua = !empty($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'no ua';
        $charset = !empty($_SERVER['HTTP_ACCEPT_CHARSET']) ? $_SERVER['HTTP_ACCEPT_CHARSET'] : 'no charset';
        $ip = substr($ip, 0, strrpos($ip, '.') - 1);
        return md5($ua . $ip . $charset);
    }
}
2 голосов
/ 12 ноября 2010

Не пытайтесь написать собственную схему сеанса, PHP сделает это лучше.

да, вы можете добавить дополнительную информацию в вашу $ _SESSION, чтобы предотвратить угон сеанса

, например, я генерирую отпечаток пальца, комбинируя секретную фразу или случайные данные с пользовательским агентом и session_id ()и хэш все это.Чтобы перехватить сеанс, пользователь должен определить действительный идентификатор сеанса и хэш отпечатка пальца.это будет выглядеть так Это хорошее чтение

$_SESSION['fingerprint'] = md5('somethingSecret' . $_SERVER['HTTP_USER_AGENT']. session_id());

, тогда вы бы проверили сеанс как

$check_print = md5('somethingSecret' . $_SERVER['HTTP_USER_AGENT']. session_id());

if($check_print != $_SESSION['fingerprint'] || $_SESSION['authenticated']){ 
    //invalid session
}
1 голос
/ 16 ноября 2010

Вы ничего не можете сделать, кроме использования HTTPS.

Не имеет значения, сколько файлов cookie вы добавляете или какие данные хэшируете;все это можно прослушать и отправить обратно на сервер.

Если вы собираетесь заставить пользователя использовать один UA в течение срока действия его запроса, это может помочь: вам не нужны никакие специальныебизнес хэширования, потому что вы хэшируете его в $_SESSION, к которому ни пользователь, ни угонщик не могут получить прямой доступ, так зачем беспокоиться о хэшировании?Также можно просто сохранить $_SESSION["reportedUA"] = $_SERVER["HTTP_USER_AGENT"] при входе в систему и затем проверять reportedUA при каждом запросе.

Это тоже тривиально для взлома, как только вы поймете, что это происходит, так как вам нужно только прослушать сообщенноеUA, когда вы прослушиваете cookie-файл сессии и начинаете его использовать.

Что дальше?Айпи адрес?Перехват сеанса может происходить из-за NAT, и в этом случае вы облажались.Ваши пользователи могут использовать дозвон, в этом случае они привинчены.

Эта проблема не имеет решения: нет способа .Там не может быть пути.Если хакер увидит ваши сеансовые куки, он может испортить вас, потому что нет никакой дополнительной информации или проблемы, связанной с чем-то, что знает только пользователь (то есть пароль), которое отправляется с каждым запросом.

Единственный способсделать сеанс безопасным - это защитить весь сеанс.

1 голос
/ 15 ноября 2010

По состоянию на 15 ноября два ответа, которые я получил, не относятся к моему вопросу, который был

«Является ли эта [отдельная переменная сеанса] достаточно сильной мерой безопасности?»

Этот вопрос говорит «да», но, похоже, что-то расходится.Вот краткое изложение различных результатов:

1) Одной переменной сеанса недостаточно безопасности , поскольку сеанс может быть довольно легко взломан .

2) Поскольку это может произойти, ни один сеанс не является по-настоящему безопасным, но его можно сделать более безопасным, добавив отпечаток пальца.Это обеспечивает уникальную повторяемую проверку каждый раз, когда сеанс нуждается в проверке.@zerkms рекомендует хэш User-Agent и некоторые другие (см. его код).

3) Соль отпечатка пальца в основном бесполезна, поскольку она скрывает данные, но реплицируется на каждом клиентском компьютере, теряя свою уникальность.

4) База данныхРешение бесполезно, так как это проблема на стороне клиента.

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

Чтение этогопомогло / смутило меня далее:

Перехват сеанса и PHP

Является ли HTTPS единственной защитой от перехвата сеанса в открытой сети?

0 голосов
/ 26 июля 2013

Это достаточно сильная мера безопасности,

Установите две переменные сеанса для проверки друг друга и / или
Реализация базы данных / проверка хеша

Нет, и причина в том, что все, что ваш действительный пользователь может отправить на ваш сервер для проверки подлинности (идентификатор сеанса, файлы cookie, некоторая хэшированная строка, что угодно!), Может быть прослушано другими, если оно не зашифровано. Даже если сервер обрабатывает данные с помощью хеширования md5, соли, двойных проверок переменных сеанса, идентификатора или чего-либо еще и сохраняет эту информацию, он легко воспроизводится сервером, когда он снова получает поддельные данные из какого-либо другого источника.

Как и предполагали многие, SSL - единственный способ предотвратить этот тип перехвата.

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

Эй, что по этому поводу:

Создайте одноразовый идентификатор GUID и произвольную соль и зашифруйте его с помощью общего пароля с помощью PHP - он отправляется как идентификатор сеанса или файл cookie.

Клиент получает cookie, расшифровывает его с помощью общего пароля с использованием javascript (доступно множество утилит enc / dec)

Установите текущий идентификатор cookie или идентификатора сессии в GUID.

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

SSL кажется намного проще, но все же более безопасным.

РЕДАКТИРОВАТЬ : Хорошо, это было сделано - не важно; -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...