Пожалуйста, критикуйте мои попытки аутентификации PHP

После публикации этого вопроса я решил создать свою собственную функцию регистрации / аутентификации в PHP. Я хотел бы, чтобы кто-нибудь указывал на недостатки / возможности для улучшения, особенно вокруг того, что хранится в сессии …

Логический поток:

1 – Пользователь регистрирует, используя электронную почту как имя пользователя, «имя сайта», которое затем составляет часть любого URL-адреса, к которому у них будет доступ, и пароль не менее 6 символов, который должен содержать буквы и цифры (я знаю, что это может быть сильнее)

2 – При условии, что пользователь и сайт уникальны, я затем сохраняю оба из них вместе со случайно созданной строкой (солью) в строке в таблице auth в моей базе данных. Затем я беру пароль пользователей, объединяю соль и сохраняю хеш md5 этого соленого пароля в той же строке базы данных

3 – Когда пользователь вступает в систему, я беру пароль, который она вводит, и объединяет соль, создавая хеш-память md5 и сравнивая его с тем, что я хранил в базе данных – если они совпадают, пользователь ввел правильный пароль, и их имя пользователя записывается на сеанс

4 – По каждому запросу я использую имя пользователя, сохраненное в сеансе, для запроса базы данных и чтения имени сайта, связанного с этим пользователем. Затем я сравниваю это с именем сайта в самом URL-адресе, и если они совпадают, я устанавливаю переменную, доступную для остальных или скриптов (а не глобальную переменную, она просто читается моим контроллером, который решает, может ли пользователь видеть конкретная страница), если два имени сайта не совпадают, пользователь перенаправляется обратно в логин

Мое беспокойство заключается в том, может ли кто-нибудь писать на сессию и, таким образом, иметь доступ к страницам людей, если они знают имя пользователя, с которым они подписались? Как бы вы это сделали?

Прежде, чем кто-либо обвинит меня в небрежности, кстати, это личный проект для обучения – я не подвергаю данные клиентам!

Solutions Collecting From Web of "Пожалуйста, критикуйте мои попытки аутентификации PHP"

  1. Почему 6 символов? Сделайте его больше и потребуйте минимум 6 (или более) символов. Нет никакого оправдания для ограничения количества символов в пароле до 6.

  2. Поместите больше, чем имя пользователя в сеанс. Но чтобы сделать это безопасно, вы должны изменить соль каждый логин:

A- На странице входа: введите имя и пароль с помощью существующей соли. Если действительное обновление солидной таблицы пользователя и пароля с помощью новой соли (у вас есть пароль от пользователя, чтобы вы могли снова md5 и соль). Напишите md5 пароля для сеанса. B- С любой другой страницы: сравните пользователя и хешированный пароль с базой данных. Если они не совпадают, перенаправляйте страницу входа.

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

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

Вы также можете изучить CAPTCHA, чтобы ограничить регистрацию с помощью скриптов.

Короткий ответ: хорошо выглядит!

Длительный ответ:

  1. Да, вы должны разрешать более сильные / более длинные пароли, но в остальном это нормально. Просто убедитесь, что вы принимаете только действительные символы URL-адреса (я буду придерживаться символов слова PCRE) для имени сайта. Тем не менее, система «проверять эту электронную почту» была бы уместной, чтобы убедиться, что владелец регистрации фактически контролирует предоставленный адрес электронной почты.
  2. Выглядит неплохо. Мне нравится sha1 лучше, чем md5.
  3. Пока ваши сеансы безопасны, вы можете хранить больше, чем просто имя пользователя (что будет довольно дорогостоящим поиском SQL для каждого запроса страницы – продолжите и сохраните их PK).
  4. Выглядит неплохо, но должен быть скорректирован по моим комментариям в # 3

Чтобы убедиться, что вы правильно обрабатываете безопасность сеанса, проверьте руководство по PHPSec .

  • Ограничьте скорость на входах. Запишите каждую попытку для пользователя и заблокируйте их после стольких неудачных попыток. По мере того, как неудачные попытки монтируются, заблокируйте блокировку дольше и дольше.

  • Добавьте соль в свой статический код и используйте его в сочетании с солью из базы данных. Тогда, если вы дБ взломали, у них все еще нет соли из кода. Эта соль не может / не должна изменяться.

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

  • Когда пользователи перезагружают свои пароли, они должны знать исходный?

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

Зачем солить код, а также базу данных? Как только ваша база данных взломана, ваш сайт тост. Однако, видя, что пользователи склонны использовать один и тот же пароль на многих сайтах, нет смысла помогать взломать всю собственность. Если они тоже получат ваш код, тогда произойдет королевская ошибка, но позволит нам преодолеть как можно больше барьеров.

Безопасность через неясность глупо, но многие уровни безопасности могут помочь.

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

Вы даже можете восстановить это соленое значение в каждом представлении X-страниц и сохранить в сеансе, чтобы его закончить, и сделать воровство менее полезным с течением времени. Затем вы будете хранить две соли в своей базе данных. Один для пароля, один для значения сеанса аутентификации.

Если кто-то наблюдает за регистрационной формой, то у них есть информация, о которой вы беспокоитесь, они поймут. Первый шаг: используйте HTTPS для ваших форм.

Что же касается зашифрованного файла db, я позволю кому-то еще решить проблему. 🙂

Мое беспокойство заключается в том, может ли кто-нибудь писать на сессию и, таким образом, иметь доступ к страницам людей, если они знают имя пользователя, с которым они подписались? Как бы вы это сделали?

Я не уверен, что вы имеете в виду. Как кто-нибудь «напишет на сессию»? Сессия [обычно] – это файл, хранящийся на сервере, который клиент не может просмотреть или изменить.

Если вас беспокоит захват сеанса (aka fixation), вам необходимо включить SSL и отключить идентификаторы сеанса в строке URL. (См. Php.ini's session.use_only_cookies )

4 – По каждому запросу я использую имя пользователя, сохраненное в сеансе, для запроса базы данных и чтения имени сайта, связанного с этим пользователем. Затем я сравниваю это с именем сайта в самом URL-адресе, и если они совпадают, я устанавливаю переменную, доступную для остальных или скриптов (а не глобальную переменную, она просто читается моим контроллером, который решает, может ли пользователь видеть конкретная страница), если два имени сайта не совпадают, пользователь перенаправляется обратно в логин

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

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

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