Очень красиво иллюстрированный вопрос!
Следует отметить, что поддержка PHP-сессий заключается в том, что она тоже использует куки. PHP автоматически устанавливает cookie с идентификатором сессии, который назначает PHP. Затем он автоматически читает этот файл cookie и загружает сеанс.
Теперь файлы cookie могут быть похищены (см., Например, Firesheep ) "человеком в середине атаки". Атакующий просто копирует куки другого человека (которые отправляются вместе с каждым запросом) и добавляет их в свой собственный браузер. А поскольку сеансы идентифицируются с помощью файлов cookie, вы можете захватить сеанс таким образом (злоумышленник просто будет использовать сайт с тем же сеансом, что и пользователь). Или вы можете захватить cookie-файл "Запомнить меня" для дальнейшего использования.
Единственная реальная защита от таких угонов - иметь зашифрованное соединение, то есть соединение "https". Затем данные cookie, отправляемые взад и вперед, будут шифроваться для каждого запроса, поэтому кто-то другой не сможет скопировать его фактическое содержимое.
В противном случае у вас есть правильное представление о том, как сопоставить cookie-файл с постоянным входом в систему для пользователя (т. Е. Хэш в cookie-файле должен совпадать с таким же в базе данных). Для проверки сеанса вам не нужно никакого хэширования, поскольку сами данные сеанса никогда не покидают сервер. Таким образом, вы можете просто установить $_SESSION['logged_in_user_id']
в UID - или в false / null, если они не вошли в систему. То есть, если cookie проверяется или имя пользователя / пароль проверяются, затем установите идентификатор пользователя в сессия как простой int.
Что касается «ручного» входа в систему, когда пользователь отправляет свое имя пользователя и пароль, вы снова подвергаетесь воздействию человека в середине атаки. Как и раньше, это просто вопрос перехвата данных, отправляемых на сервер. Если вы не используете зашифрованное соединение, файлы cookie и имя пользователя / пароль (и все остальное) будут в открытом тексте и легко читаемыми для злоумышленника.
Незначительные баллы:
Для алгоритма хеширования я бы выбрал sha1
, а не более старый md5
. И для имени пользователя / пароля в базе данных, никогда не стоит хранить пароль как открытый текст в базе данных. Если ваша база данных будет взломана, злоумышленники могут просто прочитать там все, независимо от того, насколько безопасно ваш сервер взаимодействует с вашими пользователями.
Вы, наверное, уже знаете все это, но на всякий случай: для таблицы пользователей сохраните имя пользователя в виде открытого текста, но также сгенерируйте соль (скажем, хешируйте текущее время плюс произвольную - но постоянную! - определяемую вами строку, и хэш это несколько раз несколько раз). Сохраните соль в базе данных и используйте ее при хешировании пароля. И снова, хэшируйте это многократно много раз. Наконец, сохраните хешированный пароль в БД. Вы не сможете отправлять людям их пароли, потому что вы тоже не знаете (вы просто знаете хеш), но вы можете реализовать опцию «сбросить пароль», которая генерирует новую соль и случайную строку, которая Вы тогда хешируете как любой другой пароль. Просто не забудьте хранить новый пароль без хеширования достаточно долго, чтобы отправить его пользователю. Причина, по которой вы хотите хэшировать его несколько раз, заключается в том, что он делает невозможным использование радужного стола для «реверсирования» хеширования, даже если вы знаете соль (и). Если вы только что хешировали пароль один раз, с md5 и без соли, было бы тривиально посмотреть хеш и посмотреть, что такое нехэшированный пароль (если только ваши пользователи не достаточно умны, чтобы использовать действительно длинные случайные пароли, которые не встречается в любых радужных таблицах).
Короче говоря: сеанс, файлы cookie и имя пользователя / пароль уязвимы для одного и того же вида атаки. Наиболее практичной защитой от этого является использование SSL (поскольку, как вы заметили, IP-адреса меняются).
Также смотрите другие ответы. Чем больше информации, тем лучше :) 1027 *