Безопасность входа в PHP

Вот как я строю систему входа в систему:

Авторизоваться:

  1. Проверьте имя пользователя и пароль, предоставленные пользователем в базе данных.
  2. Если имя пользователя и пароль верны, сохраните только идентификатор пользователя в сеансе, например:

    $ _SESSION [ 'идентификатор пользователя'] = $ Идентификатор_пользователя;

  3. Если Пользователь установил флажок для входа в систему, затем установите 2 файла cookie, 1 с идентификатором пользователя и другой хэшированной строкой.

Чтобы проверить, вошел ли пользователь в систему:

  1. Проверьте, существует ли сеанс, пользователь регистрируется. Это нормально?
  2. Если сеанс не существует, проверьте, существуют ли файлы cookie, userID и хешированная строка.
  3. Если оба файла cookie существуют, проверьте их.

Как сеанс хранится на сервере, безопасно ли хранить только идентификатор пользователя? Может ли пользователь притвориться другим пользователем и сохранить свой идентификатор пользователя в сеансе и войти в систему как он? Благодарю.

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

Редактировать:

Если вы собираетесь использовать незашифрованные файлы cookie, почему бы просто не сохранить session_id в таблице базы данных? Таким образом, по крайней мере, у кого-то, у кого есть куки-файл, не будет действительного имени пользователя. Создайте таблицу сеансов, и когда кто-то успешно завершит аутентификацию, добавьте строку со своими user_id и session_id. Каждый раз, когда страница загружается, проверьте, соответствует ли session_id в cookie строке в таблице сеансов. Если да, вы можете предположить, что связанный user_id является аутентифицированным пользователем. Этот подход столь же безопасен, как тот, который вы предложили (т. Е. Не очень), но он менее сложный и не дает достоверных имен пользователей.

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

Лучшей защитой является, конечно же, SSL, но если вы не можете использовать ее на своем веб-сайте, есть и другие вещи, которые могут предотвратить (но не полностью защитить) от этих атак:

  • Сохраняйте информацию о пользователе на стороне сервера при входе в систему, хорошими кандидатами на это являются IP и пользовательский агент , но любые другие данные, которые не изменяются во всем сеансе, могут быть действительными.
  • Вы можете восстановить идентификатор сеанса в каждом запросе, при этом, если идентификатор сеанса просочился, злоумышленник должен использовать его до того, как реальный пользователь выполнит какой-либо другой запрос, но будьте осторожны, потому что каждый раз, когда идентификатор сеанса регенерируется (по крайней мере, в PHP) данные сеанса переписываются , поэтому это может быть дорого, если у вас много пользователей или вы сохраняете много данных каждого пользователя (это означает, что если вы сохраняете данные сеанса в файле, файл будет удален, создан , и снова повторил).

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

Еще одна вещь: не доверяйте cookies пользователя, они могут быть изменены пользователем (или злоумышленником) в любое время, рассматривают его как любой другой пользовательский ввод.

PD .: Извините за мой ужасный английский, я действительно пытаюсь его улучшить ^ _ ^

вы можете добавить ip, к которому должен принадлежать идентификатор пользователя (в вашей базе данных), который добавляет немного дополнительной безопасности – это может быть не всегда лучшее решение

Да, нормально проверить, существует ли сеанс, а также проверить, что идентификатор пользователя больше нуля.

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

Предполагая, что это происходит через SSL, моя самая большая забота – это ваш первый шаг:

  1. Проверьте имя пользователя и пароль, предоставленные пользователем в базе данных.

Вы должны быть хешировать пароли и сравнивать хэш пароля, предоставленного пользователем, с ранее сохраненным паролем, хранящимся в вашей базе данных.

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

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

Крис Шифлетт предлагает создать какой-то отпечаток пальца из строки User-Agent или какой-либо другой регулярный заголовок и сохранить его в переменной GET.

Один из способов повысить безопасность – это все , что отправлено через SSL. Каждый раз, когда какая-либо потенциальная информация отправляется или принимается (например, идентификатор сеанса в cookie-файле), зашифруйте ее, а не только форму входа.

Это в основном правильно, но я не согласен с вариантом cookie. Таким образом, если кто-то получит два файла cookie, они смогут переместить их на другой компьютер и использовать их.

Функция «оставаться в системе» должна быть ограничена этим компьютером. Возможное решение заключается в том, что если пользователь хочет остаться в системе, вы установите время жизни сеанса на 1 неделю или около того. Также вы должны сохранить IP-адрес пользователя, User-Agent и, возможно, заголовок X-FORWARDED-FOR, и проверить их на каждой странице с сохраненными значениями.