Сценарий:
session
Вопрос:
Является ли это достаточно сильной мерой безопасности самостоятельно или я должен
========
(Кстати, пока я изучал этот вопрос, эта вики – фантастическое чтение.)
Достаточно хранить только пользовательский логин (или идентификатор пользователя) в сеансе.
Чтобы предотвратить фиксацию / захват сеанса, все, что вам нужно, это просто реализовать простой алгоритм (псевдокод):
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'); }
Вы можете переместить вычисление хэша в некоторую функцию, чтобы предотвратить дублирование, я только что показал эскиз возможной защиты.
Вот как я реализовал такую защиту в моем классе сеанса kohana:
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); } }
Не пытайтесь написать свою собственную схему сеанса, PHP сделает это лучше.
да, вы можете добавить дополнительную информацию в свою $ _SESSION, чтобы предотвратить захват сеанса
например, я генерирую отпечаток пальца путем объединения секретной фразы или случайных данных с пользовательским агентом и session_id () и хеширования. Чтобы захватить сеанс, пользователю необходимо выяснить действительный 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 }
Вы ничего не можете сделать, кроме использования HTTPS.
Неважно, сколько файлов cookie вы добавляете или какие данные вы используете; его все можно обнюхать и отправить обратно на сервер.
Если вы собираетесь заставить пользователя использовать один UA в течение всего срока их запроса, это может помочь: вам не нужен какой-либо особый бизнес хеширования, потому что вы хешируете его в $_SESSION
который ни пользователь, ни угонщик может получить доступ напрямую, так зачем беспокоить его? Также можно просто сохранить $_SESSION["reportedUA"] = $_SERVER["HTTP_USER_AGENT"]
при входе в систему, а затем проверить reportedUA
по каждому запросу.
Это тоже тривиально для захвата, как только вы осознаете, что это происходит, поскольку вам нужно только обнюхивать сообщенный UA, когда вы нюхаете куки-файлы сеанса и начинаете использовать это.
Что дальше? Айпи адрес? Захват сеанса может происходить из-за NAT, и в этом случае вы будете ввернуты. Ваши пользователи могут использовать dial-up, и в этом случае они завинчиваются.
Эта проблема не имеет решения: нет способа . Не могло быть способа. Если хакер может видеть ваши файлы cookie сеанса, они могут вас повредить, потому что нет никакой дополнительной информации или проблем, связанных с чем-то, что пользователь знает (т.е. пароль), который отправляется с каждым запросом.
Единственный способ сделать сеанс безопасным – это обеспечить безопасность всего сеанса.
По состоянию на 15 ноября два ответа, которые я получил, не затрагивают мой вопрос, который был
«Является ли это [единственной переменной сеанса] достаточно сильной мерой безопасности?»
Этот вопрос говорит «да», но, похоже, есть разногласия. Ниже приведен краткий обзор различных результатов:
1) Одной переменной сеанса недостаточно, так как сеанс может быть легко захвачен .
2) Поскольку это может произойти, сеанс не является действительно безопасным, но его можно сделать безопаснее с добавлением отпечатка пальца. Это гарантирует уникальную повторяющуюся проверку каждый раз, когда сессия требует проверки. @zerkms рекомендует хэш User-Agent
и несколько других (см. его код).
3) Соление отпечатка пальца в основном бесполезно, поскольку оно затушевывает данные, но реплицируется на каждом клиентском компьютере, поэтому теряется его уникальность.
4) Решение базы данных бесполезно, так как это проблема на стороне клиента.
Не тот окончательный ответ, который я искал, но я полагаю, что это будет нужно, потому что ничего лучше.
Чтение, которое помогло / смутило меня дальше:
Захват сеанса и PHP
Является ли HTTPS единственной защитой от захвата сеанса в открытой сети?
Является ли это достаточно сильной мерой безопасности,
Задайте две переменные сеанса для проверки друг друга и / или
Внедрить проверку базы данных / хеширования
Нет, и причина в этом: все, что ваш действительный пользователь может отправить на ваш сервер для проверки подлинности (идентификатор сеанса, файлы cookie, некоторые хэшированные строки, что угодно!), Могут быть обнюханы другими, если они не зашифрованы. Даже если сервер обрабатывает данные с помощью хэширования md5, солей, проверок с двойной сессией, идентификатора или чего-то еще, и сохраняет эту информацию, он легко воспроизводится сервером, когда он снова получает поддельные данные из другого источника.
Как и многие люди, SSL является единственным способом предотвратить этот тип evesdropping.
Мне пришло в голову, что сервер должен генерировать новый идентификатор сеанса для каждого запроса и разрешать браузеру отвечать только один раз, теоретически может быть только один запрос или сообщение угонщика перед сервером, и авторизованный браузер знал о Это. Однако все же неприемлемо, потому что одного достаточно, чтобы нанести серьезный урон.
Эй, как насчет этого:
Создайте единый GUID и произвольную соль и зашифруйте его с помощью общего пароля с помощью PHP – это отправляется как идентификатор сеанса или файл cookie.
Клиент получает файл cookie, расшифровывает его с помощью общего пароля с помощью javascript (есть много доступных утилит /
Установите текущий файл cookie или идентификатор сеанса на идентификатор GUID.
Это гарантирует, что никто не сможет захватить сессию, если они не знают пароль, который никогда не отправляется по сети.
SSL кажется намного проще и безопаснее.
EDIT : Хорошо, это было сделано – nevermind 😉