#php #security
#php #Безопасность
Вопрос:
Я немного новичок в веб-разработке, и мне нужно разработать пользовательскую систему, чтобы пользователи могли регистрироваться, входить в систему и т. Д.
Изначально я сохранял пользовательские данные в переменной сеанса при входе в систему, но почувствовал необходимость перестроить ее, потому что понял, что никогда не смогу поддерживать функции «запомнить меня», и решил использовать cookies.
Моя текущая система такова:
- Пользователь входит в систему: я проверяю имя пользователя и пароль на соответствие сохраненным значениям в БД
- Я установил имя пользователя и пароль для их собственных файлов cookie. файл cookie имени пользователя сохраняется, поэтому поле имени пользователя может быть заполнено при повторном посещении пользователем. Срок действия файла cookie пароля истекает, когда пользователь уходит.
- Каждый раз при загрузке страницы мой PHP-скрипт проверяет, существует ли файл cookie с паролем, что означает, что пользователь вошел в систему.
Проблема в том, что третий шаг кажется мне несколько небезопасным. В настоящее время я только проверяю, существует ли файл cookie с паролем, но я не сравниваю его с базой данных при каждой загрузке страницы. Не мог ли неавторизованный пользователь создать файл cookie с паролем и вручную установить для него некоторую случайную строку и пройти через мою систему аутентификации? Он сможет выдавать себя за любого пользователя, также установив пользовательский файл cookie вручную. Должен ли я сравнивать значение файла cookie пароля с моей базой данных при каждой загрузке страницы?
Итак, если я использую session
в сочетании с файлами cookie, я представляю, что делаю что-то вроде этого:
if (!isset($_SESSION['user']))
{
authenticate_user_from_cookie();
set_session('user');
}
else
{
//user is already logged in
}
Ответ №1:
При вызове session_start()
он повторно подключит текущий запрос к сеансу ( $_SESSION
) или создаст новый сеанс. Apache сохраняет эти сеансы на диск (по умолчанию в вашей /tmp
папке) и автоматически подключает вас к сеансу с помощью файла cookie с именем PHPSESSID
(это можно изменить в PHP.INI
), который сохраняется после первого вызова session_start()
при первом запросе.
Вы можете аутентифицировать своего пользователя любым удобным для вас способом, но обычно вы можете использовать поиск пары имя пользователя (например, зашифрованный пароль sha1($password.'salt string that only you know')
) в вашей базе данных или постоянном хранилище, а затем просто установить $_SESSION['loggedIn'] = true
или $_SESSION['user'] = 1
или любой флаг, который вы хотите в $_SESSION
.
Вы можете зайти так далеко, что создадите User
класс (многие фреймворки делают это), представляющий все, что вы знаете о вошедшем в систему аутентифицированном пользователе, а затем запросить объект $_SESSION['User']->isAuthenticated()
или что-то в этом роде.
Если вы хотите, чтобы пользователь не вводил свой пароль повторно каждый раз, вы можете реализовать Remember Me
функцию (специальный случайный файл cookie, который вы сгенерировали при аутентификации пользователя и сохранили в базе данных), которая установит в их браузере специальный файл cookie, срок действия которого не истечет в конце сеанса, который вы просматриваете, когда кто-то вводит свой пароль.запрос, который не прошел проверку подлинности.
Комментарии:
1. Хм, это имеет смысл. Итак, если я использую
session
в сочетании с файлами cookie, мне не нужно будет обращаться к базе данных при каждой загрузке страницы. Смотрите мой псевдокод в моем вопросе: это что-то более похожее?2. Да, это сработало бы, но если вы не можете аутентифицировать их из файла cookie, вы бы перенаправили их на свою форму входа. Это позволило бы им добавлять закладки на внутреннюю страницу. Вы также можете сохранить внутреннюю страницу в
$_SESSION
, перенаправить их на свою форму входа, а затем после аутентификации перенаправить их обратно на страницу, которую они изначально запрашивали — это полезно для пользовательского интерфейса.3. Спасибо! Я обязательно включу это также.
Ответ №2:
Это не зависит от php, но если вы новичок, я бы рекомендовал прочитать руководство OWASP . OWASP — отличный ресурс для безопасной информации о веб-разработке. Сайт OWASP будет охватывать гораздо больше, чем мы можем здесь.
Для более конкретного ответа на php у них есть это руководство. Пункт 2.10 более прямо отвечает на ваш вопрос.
Ответ №3:
Простая проверка существования файла cookie ни в коем случае не является способом аутентификации пользователя или подтверждения его личности. Так что да, вы должны проверять при каждой загрузке страницы, придерживаетесь ли вы аутентификации на основе файлов cookie. Пока при поиске в пользовательской таблице есть индекс / первичный ключ, запрос будет быстро извлекать информацию о пользователе и проверять значения cookie.
Чтобы быть более конкретным, файлы cookie, которые вы устанавливаете, так же ценны, как имя пользователя и пароль пользователя, они почти синонимичны. Таким образом, вы также можете сохранять информацию о пользователе при выдаче cookie, такую как IP и User-Agent, которые вы также можете проверить, чтобы убедиться, что файлы cookie соответствуют пользователю.
Комментарии:
1. Спасибо! Это было действительно полезно. Итак, я буду каждый раз сверяться с базой данных и рассмотрю возможность добавления дополнительных полей, включающих IP и user agent.
2. Пользовательские агенты могут быть подделаны, плюс люди могут менять браузеры на одном компьютере или использовать другую машину с тем же IP-адресом (например, они подключаются через маршрутизатор).
3. Файлы cookie также могут быть подделаны — вы добавляете еще один уровень защиты, который злоумышленнику потребуется правильно установить для успешной аутентификации, хотя и относительно небольшой уровень. Лично я думаю, что если вы измените браузеры, вы должны выйти из системы, и если они используют другую машину с тем же IP-адресом, у них, вероятно, будет другой пользовательский агент, который снова отключит их.
4. Если пользователь использует другой браузер, не выйдет ли он из системы в любом случае, даже если я не пройду аутентификацию с помощью user-agent? Я всегда думал, что файлы cookie зависят от браузера, и файлы cookie, установленные одним браузером, не могут быть доступны другому браузеру.
5. @xbonez — Правильно, смысл был в том, что если они подделают файлы cookie в другом браузере, они войдут в систему, как если бы они были в исходном браузере. Добавив проверку агента пользователя, злоумышленнику придется подделать как файлы cookie, так и строку агента пользователя, чтобы успешно войти в систему
Ответ №4:
Еще несколько советов:
1.) Убедитесь, что вы выполняете проверку ввода как для пароля, так и для идентификатора пользователя, и убедитесь, что вы проверяете значения на стороне сервера, поскольку любая проверка на стороне клиента может быть легко обойдена злоумышленниками. Если вы не выполните проверку на сервере, вы откроете себя для различных типов атак, таких как внедрение SQL, и люди смогут скомпрометировать вашу базу данных. Убедитесь, что вы избегаете любых потенциально вредоносных строк
2.) Убедитесь, что у вас есть выходы из системы, чтобы, если люди попытаются ввести слишком много неправильных учетных данных, вы заблокировали их IP на несколько минут. Это предотвратит атаки методом перебора. Убедитесь, что это работает как для неверных идентификаторов пользователей, так и для неверных паролей, поскольку злоумышленники могут использовать любой из них (например, они могут сохранить пароль одинаковым и попробовать несколько идентификаторов пользователей).
3.) Если вы используете соли, не храните соль в том же месте, что и хэши паролей. Если кто-то взломает вашу базу данных, вы не хотите, чтобы у них были как хэши, так и соли, потому что это упростит взлом хэшей с помощью rainbow tables.
4.) Убедитесь, что вы используете SSL / TLS для шифрования трафика между сервером и пользователем, иначе злоумышленник может украсть cookie, прослушав сеть и войдя в систему как ваш пользователь. (Посмотрите Firesheep, это было большой проблемой для Facebook и Gmail некоторое время …)
5.) Не используйте никаких пользовательских схем шифрования, используйте только надежные криптографические библиотеки и алгоритмы для выполнения хэшей. (например, PHP sha1 хорош, а небольшая ротация символов пароля — нет).
6.) Как рекомендуется, вам следует проверить OWASP, это лучший ресурс для защиты веб-приложения.
Комментарии:
1. для пункта № 3: суть в том, чтобы сделать таблицу rainbow бесполезной, даже если злоумышленник взломал базу данных.