Совершенно очевидно, что большинство из нас, программистов PHP, не хотят, чтобы наша опубликованная работа была взломана или использована способами, которые мы не намеревались. Поэтому я особенно осторожен, когда спрашиваю о способах противодействия угону сессии. Я знаю, что есть функция session_regenerate_id (), чтобы частично противостоять перехвату сеансов, но мне было более любопытно другой метод, с которым я столкнулся:
Когда пользователь входит в систему на веб-сайте, вы берете его user_id (или другую, еще более секретную, предварительно заданную зашифрованную строку) (которая неизвестна для обычных пользователей) как строку, и вы солите ее случайными предопределенными символами, md5 (), строку и устанавливаете это как $ _SESSION [‘user_code’] = $ that_string; и каждый раз, когда этот пользователь переходит на страницу, которую вы солите, повторите процедуру и сопоставьте ее с $ _SESSION [‘user_code’], если они не совпадают; уничтожить сессию.
Так что в коде это будет выглядеть примерно так (например):
//user credentials are correct, user data is fetched from db
$_SESSION['username'] = $row[3]; //username
$_SESSION['password'] = $row[2]; //password
$_SESSION['user_id'] = $row[4]; //user_id
$salt1 = 'uNs819';
$salt2 = 'J2i';
$user_code = $salt1 . $row[4] . $salt2;
$user_code = md5($user_code);
$_SESSION['user_code'] = $user_code;
И затем вы проверяете, правильно ли это в начале каждой доступной страницы с помощью:
//fetch user credentials from db again
//$row4 is the user_id
if($_SESSION['user_code'] != md5($salt1 . $row[4] . $salt2){
session_destroy();
}
Я не думаю, что использование user_id как части шифрования является оптимальным, но это только пример. Предпочтительно я буду использовать строку md5 отметки времени, когда был создан пользователь. Но если мне было непонятно, мой главный вопрос в том, является ли этот метод устойчивым к угону сессии, почему / почему нет?
Вам не нужна причудливая схема с несколькими солями.
Кроме того, если я смогу украсть файл cookie сеанса пользователя, ваша схема не будет работать вообще.
Измените идентификатор сессии после входа в систему, чтобы избежать фиксации сессии
Используйте HTTPS везде
Используйте http-сессионный cookie-файл, чтобы JavaScript не мог его прочитать
Проверяйте и отклоняйте ввод XSS и избегайте пользовательских данных на выходе
Используйте длинный случайный идентификатор сессии
Повторно подтвердить подлинность пользователя для важных операций
Всегда проверяйте любые формы по токенам подделки между сайтами, например, при входе создайте их токен:
Session:set('token', md5(uniqid());
Затем на каждой форме поместите скрытый ввод формы с указанным токеном.
<input type="hidden" name="crsf" value="<?php echo System::escape(Session::get('token'));">
Затем вы можете проверить их, чтобы убедиться:
if(Request::post('crsf') == Session::get('token'):
//do what you gotta do
Убедитесь, что вы генерируете новый токен при каждой отправке формы независимо от того, был он успешным или нет
Я прошу прощения за использование методов для этого, но вы получите суть, как обрабатывать формы, а что нет.
«Еще один метод, с которым я столкнулся», — приведите, пожалуйста, ваши источники.
То, что вы здесь описываете, никак не влияет на угон сеанса. Не имеет значения, сколько значений сеанса, сколько солей и сколько циклов шифрования вы используете, результат всегда будет совпадать. Если сеанс скомпрометирован, вы не можете полагаться на него для проверки сеанса. Функция session_regenerate_id () добавляет небольшое значение, но только уменьшает окно для использования существующей уязвимости. Потратьте свое время на предотвращение компрометации сеанса — используйте https, HSTS, http-only + безопасные флаги cookie, строгий CSP, уничтожение сеанса по истечении срока действия.
Если вы действительно чувствуете необходимость дальнейшего повышения безопасности, используйте токен при обычном обмене, например, ответ на вызов с использованием локального хранилища или устройства снятия отпечатков пальцев.