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

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

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

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

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

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

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

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

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

Ответ 1

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

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

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

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

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

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

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

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

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

Ответ 4

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

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

Ответ 5

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

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

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

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

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

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

Ответ 6

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