Intereting Posts

Разработка безопасной стратегии входа и аутентификации в PHP

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

Я планирую хранить следующие данные:

  • В сеансе: user-id, HTTP_USER_AGENT + HTTP_USER_AGENT

  • В файле cookie и в базе данных: случайный токен, хэшированный + соленный идентификатор

На каждой странице я планирую сделать следующее:

    1. Если сеанс существует, выполните аутентификацию с помощью этого. Убедитесь, что HTTP_USER_AGENT соответствует той, что хранится в сеансе.

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

    3. Если файл cookie недействителен или не существует, попросите пользователя войти в систему.

    Есть ли какие-то очевидные недостатки? Пока я устанавливаю тайм-аут в файле cookie, я должен быть достаточно безопасным, не так ли? Есть что-то, чего я не хватает?

    Спасибо заранее.

    Related of "Разработка безопасной стратегии входа и аутентификации в PHP"

    Несколько случайных мыслей:

    1. Что делать, если я украду файл cookie одного из ваших пользователей (используя XSS-атаку, введя код JS на свой сайт)? Затем я упаду в случае 2. и, следовательно, смогу войти в систему. ИМХО, если вы хотите действительно надежную проверку подлинности, не используйте cookie «запомнить меня» для хранения учетных данных пользователя.
    2. Если вы храните учетные данные в файле cookie, не храните его в ящике.
    3. Проверка HTTP_USER_AGENT является хорошим первым шагом для предотвращения захвата сеанса, но, может быть, вы можете объединить его с IP-адресом? Гораздо сложнее находиться на одном хосте, чем ваша цель, чем просто использовать один и тот же браузер.

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

    EDIT: для записи позвольте мне пояснить здесь: в этой дискусции есть два кука. Один из них автоматически устанавливается PHP для распространения идентификатора сеанса (иногда мы видим, что веб-сайты помещают его в URL-адрес, например http://www.example.com/page.php?sessionId = […]), а второй, созданный вами чтобы сохранить учетные данные пользователя и аутентифицировать его, когда сеанс потерян. Атака XSS применяется к обоим, то есть злоумышленник может либо украсть файл cookie сеанса, либо захватить сеанс (который имеет ограниченное время жизни), либо украсть файл cookie учетных данных и пройти проверку подлинности позже.

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

    Джо

    Хранение файла cookie в базе данных – идея HORRILBE. Это означает, что если у злоумышленника была уязвимость для инъекций sql, он мог немедленно получить доступ, не взломав хешированный пароль.

    Говоря о том, что вам нужно использовать sha256 для паролей, если вы используете md5 (), вы технически уязвимы для атаки, и вам может быть выдано CVE-номер.

    НИКОГДА не создавайте свой собственный идентификатор сеанса, используйте session_start () и супер-глобальный $ _SESSION.

    Это безопасный способ перенаправления людей. Если вы не умрете после заголовка (), остальная часть кода php будет STILL EXECUTED, даже если она не отображается обычными браузерами (хакеры все еще видят это 🙂

     header("location: index.php"); die(); 

    Если честно, если безопасность вас смущает, не пишите системы безопасности. Люди написали более 1000 систем входа для одного PHP, и большинство из них уязвимы. Этот проект имеет безопасную систему аутентификации: http://code.google.com/p/michael-the-messenger/downloads/list

    Зависит от того, насколько вы безопасны.

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

    Во-вторых: если у вас есть высокий и средний трафик, идентификаторы sessionID могут быть повторены или даже догадаться, я проверю идентификатор второй руки, который хранится в файлах cookie пользователей.

    Схема кажется излишне сложной в нескольких отношениях, поскольку добавленная сложность не дает вам ничего в функциональности или безопасности.

    1. Любые данные, отправленные браузером (например, файлы cookie, User-agent), подделываются. Проверка User-agent поможет только тогда, когда злоумышленник находится за тем же NAT, что и поддельный пользователь, и злоумышленник использует другой браузер, но не думает менять User-agent.
    2. Сеансы хранят клиентскую часть идентификатора сеанса, используя либо файлы cookie, либо параметр запроса URL. Если вы хотите продлить срок службы сеанса, используйте session_set_cookie_params чтобы сохранить cookie сеанса дольше.

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

    Атаки, которые cookie сеанса + проверка удаленного IP-адреса не будут обнаружены, следующие:

    1. злоумышленник находится за тем же NAT, что и пользователь
    2. Атаки слепых инъекций, когда злоумышленник обманывает IP-адрес пользователя. Несмотря на то, что они только для записи, они все равно могут нанести некоторый урон.
    3. атак, которые используют собственный браузер пользователя, например, подделку подпроса (CSRF).

    2) можно было бы предотвратить, если вы сможете разработать способ отправки запроса в браузер пользователя, на который необходимо ответить до завершения запроса, но это сложно, когда вы не писали клиент. С AJAX это можно сделать. 3) (как отмечено MindStalker) можно предотвратить, проверив заголовок Referer, который работает, потому что атаки CSRF не имеют возможности влиять на произвольные заголовки, а XMLHttpRequest не должен устанавливать заголовок Referer (в соответствии с W3C стандарт , хотя реализация может быть несовместимой). С помощью iframe можно было бы обойти проверку Referer. Кроме того, заголовок Referer может быть заблокирован на стороне клиента.

    Большинство сайтов просто используют сеанс PHP; данные сеанса ($ _SESSION) находятся в файле на вашем сервере. Все, что отправлено в браузер, это идентификатор сеанса. Обязательно обновите сеанс каждого запроса ( session_regenerate_id ). Вам не нужно отправлять два куки или что-то еще.

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

    Лучшим решением, очевидно, будет использование SSL на протяжении всего сеанса.

    IMHO также важно, чтобы информация о сеансе была изменена после успешного входа в систему. Для сохранения информации о сеансе в базе данных не сохраняется из-за инъекций.

    -use sha1 с солью – конечно, вы должны определить, что каждая форма небезопасна, поэтому используется токен для каждой формы. Чтобы вы создавали каждую запись и обрабатывали ее, используйте preg_match. Процесс, называемый санитарии.