PHP Session Security для входа на сайт - PullRequest
1 голос
/ 19 декабря 2010

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

Я настроил сценарий на использование HTTP только для файлов cookie и только дляиспользовать куки для хранения идентификатора сеанса.

В основном, я хотел бы знать две вещи

1. Что еще мне нужно сделать, чтобы мой логин был болееsecure?

и

2. В руководстве по PHP сказано, что session_destroy() удаляет данные сеанса, но не сбрасывает ни одну из переменных сеанса.Если это так, что это на самом деле разрушает, и я должен вручную сбросить переменные сеанса при выходе из системы?

Спасибо за любую помощь

РЕДАКТИРОВАТЬ: Я используюбесплатный хостинг и не может устанавливать какие-либо дополнения Apache или изменять файл php.ini

РЕДАКТИРОВАТЬ: Я прочитал, что использование SSL требуется для предотвращения кражи идентификатора сеанса, но яу меня нет возможности установить OpenSSL на сервер, так есть ли какой-нибудь другой способ защитить идентификатор сеанса?

Ответы [ 5 ]

12 голосов
/ 19 декабря 2010

Самое важное, что нужно запомнить:

Не верьте НИЧЕМ, что приходит от клиента

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

1.) Убедитесь, что ваша сессия зашифрована. Если вы используете встроенные сессии PHP, связанная с этим энтропия (случайность) относительно высока, поэтому с вами все будет в порядке.

2.) ТОЛЬКО сохраняйте идентификатор сессии в файле cookie. Любая другая информация должна быть просто связана на сервере с использованием этого идентификатора. Я видел много случаев, когда системный инженер определяет, является ли кто-то администратором, если в сеансе токен is_admin = true. Очевидно, вы можете увидеть проблему с этим.

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

3.) Проверить по IP - добавьте в свою таблицу текущий IP-адрес. Если текущий IP-адрес не совпадает с IP-адресом в сеансе, возможно, кто-то пытается взломать его. Принудительно выйти и прекратить.

4.) Установите ограничения на попытки входа в систему. Добавление 1 секунды сна (); серверная сторона при каждом входе в систему практически незаметна для пользователя, но для автоматизированной системы практически невозможно сделать грубый принудительный вход в систему.

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

6.) Меньше заботьтесь о безопасности PHP и SSL и больше вашей собственной логики. Тот факт, что веб-сайт использует SSL, не делает его безопасным. SSL в сочетании с правильной логикой обеспечивает безопасность.

7.) Если вы заинтересованы в СУПЕР, вам нужно перейти на выделенный сервер. Возможно, что другие веб-сайты, размещенные на вашем сервере, могут иметь доступ к вашей информации о коде / базе данных. Возможно, они не предпринимают необходимых шагов, чтобы быть в безопасности, как вы.

8.) Не разрешать одновременные сеансы. Это предотвращает атаку MITM (человек посередине). Еще одним преимуществом подхода к сеансу БД является то, что вы можете принудительно выйти из системы, если два клиента пытаются одновременно войти в систему с разных IP-адресов. Еще одно преимущество подхода БД заключается в том, что он делает вашу систему масштабируемой (поскольку хранилище сеансов зависит от файловой системы).

9.) Используйте mysql_real_escape_string вместо add_slashes

Если вам нужна дополнительная информация о безопасности с помощью PHP, это моя специальность. Не стесняйтесь связаться со мной.

1 голос
/ 19 декабря 2010

1) Используйте https.Как минимум, страница входа в систему должна использовать https для защиты пароля пользователя, но вы должны рассмотреть вопрос о том, чтобы весь сеанс аутентификации использовал https для предотвращения кражи cookie.

Требуются как cookie, так и данные POSTсодержать правильный токен аутентификации.

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

2) session_destroy фактически делает недействительным куки-файл сеанса клиента, поэтому будущие запросы не будут видеть тот же сеансданные.В зависимости от вашего потока кода вы можете либо сделать session_destroy последним, что вы делаете перед возвратом к клиенту, либо вручную сбросить суперглобальное содержимое $_SESSION.

1 голос
/ 19 декабря 2010

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

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

Когда вы session_destroy(), вы очищаете связь на стороне сервера между Id и переменными, делающими сеанс непригодным для использования.У клиента все еще может быть идентификатор, но теперь он бесполезен.

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

РЕДАКТИРОВАТЬ: Re ваш SSL Вопрос:

SSL поддерживается практически на каждом современном сервере.(Вам действительно нужно искать сервер, который его не поддерживает).OpenSSL является одним из многих программных продуктов, которые реализуют SSL.

Основы SSL заключаются в следующем: Вы получаете сертификат *, который установлен на сервере.Сервер использует этот сертификат для «подписания» каждого запроса и шифрования передачи между клиентом и сервером.

* Сертификаты можно создавать бесплатно (Google « самоподписанные сертификаты »), но самостоятельноПодписанные сертификаты обычно дают пользователю предупреждение / ошибку в зависимости от браузера (так как уровень доверия не подразумевается).У браузеров есть список «доверенных» издателей сертификатов - Verisign, Thawte и многие другие.Это хорошо зарекомендовавшие себя компании, которые выдают сертификаты (обычно за определенную плату).

Сертификат действителен в течение определенного периода времени и имеет различные уровни доверия (например, дешевые просто проверяют правильность адреса электронной почты, Расширенная проверка сертификаты выдаются только после того, как эмитент проверил номера телефонов, паспорта, адреса электронной почты и зарегистрированный адрес).

У EV-сертификатов есть некоторые преимущества (а также значок замка, выполучить зеленую адресную строку - см. www.paypal.com) Вам нужно будет решить, насколько это важно для вас.

Вам следует связаться со своим хостом, чтобы спросить, можете ли вы добавить сертификат SSL.Раньше было так, что это обычно было доступно только для платных учетных записей, но в настоящее время это становится все более распространенным - так что вы бы хотели найти бесплатный хостинг SSL, если вы немного Google

0 голосов
/ 02 декабря 2018

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

hash('md5', 'special-phrase_' . time() . '_special-phrase');

И на принимающей стороне я запускаю цикл, который работает следующим образом.Токен будет бесполезен через 1 минуту.

for ($i=0; $i<=60; $i++) {
    $phrase = hash('md5', 'special-phrase_' . (time() - $i) . '_special-phrase');
    if ($phrase == $token) {
        print('Request received from a trusted client.'); exit;
    }
}
print ('Request timeout!')!

Я использую эту технику в моей системе входа в систему, это правильный способ обработки доверенных данных?Пожалуйста, дайте ваши предложения.Спасибо!

0 голосов
/ 19 декабря 2010

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

...