Работа с файлами сессий и cookies в PHP и MYSQL
Безопасность является важной составляющей успеха каждого сайта. Тем не менее, неправильное повышение уровня безопасности может привести к увеличению затрат и общему раздражению пользователей. В данном руководстве мы рассмотрим общие проблемы, которые встречаются при работе с файлами сессий и cookies.
Файлы Cookie
Файлы Cookies – способы идентификации пользователя сайтом. Например, сайт создаёт файл cookie с именем: “favorite_color” и значением: “red”. С этого момента всякий раз при посещении сайта будет загружаться файл cookie, и устанавливать, что ваш любимый цвет – красный (“favorite_color” is “red). Это довольно удобно, так как пользователю не приходится каждый раз регистрироваться в системе при посещении сайта. Этот метод используется также в опции “Remember Me”, которая встречается на многих сайтах. Однако этот способ также может создать серьёзные бреши в системе безопасности сайта.
Один пример не подтверждает, какой именно файл cookie вернётся на ваш сайт. После несложного поиска я нашёл веб-сайт со сценарием панели пользователя. Данный сценарий вывел все мои данные входа в систему в файлах cookie и загружал значения каждый раз во время выполнения действия. Например, если я оставлял комментарий, система выдавала любое из моих имён из переменной имён файла cookie. Далее, используя расширение firebug и пару других устройств, я мог не только просматривать эти файлы, но также и редактировать их. Таким образом, всякий раз, когда я редактировал файл cookie содержащий моё имя, сайт не подтверждал правильность имени, а выводил данные. Также я мог изменять свой ID. В конечном итоге я смог найти ID администратора (001) и получить доступ на правах администратора.
Сессии
Сессии – это переменные для идентификации пользователей, хранящиеся на вашем сервере. В отличие от файлов cookie, пользователи не могут изменять их напрямую, но в то же время риск ещё существует. Есть две основные угрозы для сессий: фиксация сессии и перехват сессии.
Фиксация сессии
Фиксация сессии происходит, когда пользователи подключаются к уже установленной сессии и загружают туда свою информацию. Посредством входа в уже установленную сессию злоумышленник может посетить данную сессию и получить информацию, введённую пользователями. Простой пример - пройти по ссылке на веб-сайт с уже установленным идентификатором сессии (session ID). Например, http://www.example.com/?PHPSESSID=1234. Теперь для просмотра вашей информации злоумышленник использует тот же идентификатор PHPSESSID.
Перехват сессии
Перехват сессии – второй вид атаки, от которого гораздо сложнее защититься. В этом случае злоумышленник может завладеть вашим идентификатором сессии посредством анализа пакетов (данных) и иных всевозможных способов. Например, злоумышленник, подключённый к вашей сети, может фильтровать все ваши данные, посылаемые на маршрутизатор. После получения вашего идентификатора сессии злоумышленник может посетить данный идентификатор для получения доступа ко всей вашей информации.
Эффективное использование сессий
В данном руководстве не описывается процесс кодирования сценария регистрации. Однако я постараюсь показать, как сделать более безопасным ваш текущий сценарий регистрации.
В целом использование сессий безопаснее использования файлов cookie. Это объясняется тем, что пользователи не могут изменять значения сессий так же легко, как и значения файлов cookie. Вот почему мне нравится хранить все переменные пользователей в переменных сессий. Другой важный момент – никогда не доверять вводу данных пользователями. Всегда сверяйте информацию пользователя со значениями в базе данных MYSQL и соответственно затем вывод на сессию. Рассмотрите вариант внесения изменений в регистрационную функцию наподобие следующей функции:
Давайте проанализируем данный код. Он запрашивает имя пользователя и пароль и проверяет, существует ли пользователь, у которого совпадают оба этих критерия. Если результат отсутствует, образуется неверная комбинация имя пользователя/пароль и выдается ошибка. В противоположном случае создаются переменные сессии: user_id, user_level, user_name, и user_lastactive. Эти значения заполняются данными из списка mysql.
Возможно, у вас возникнет вопрос, что означает функция “session_regenerate_id(true)”. Ранее мы говорили о фиксации сессии. Это решение предназначено для защиты от данного типа атаки. Функция создаёт новый идентификатор сессии при каждом входе пользователя в систему. Таким образом, если пользователь щёлкнет по ссылке с установленным значением сессии, будет создан новый идентификатор сессии, а информация о пользователях будет добавлена в новую, а не старую сессию. При прохождении верного параметра (true) через данную функцию удаляет старую сессию и стирает всю информацию.
Написание функции “Remember Me”
Файлы cookie или файлы сессии не должны содержать паролей пользователей. Это очень важно, так как в случае перехвата файла сессии или cookie злоумышленник может получить полный контроль над всеми учётными записями. Известно, что многие пользователи используют один и тот же пароль в различных учётных записях, и это позволит злоумышленнику получить контроль над учётными записями пользователей на других сайтах. Как можно выйти из этого затруднительного положения?
Решение данной проблемы – ключ санкционирования доступа (auth_key). Ключом санкционирования доступа может быть связка из имени пользователя, пароля и произвольного набора символов, которые объединяются и зашифровываются. У каждого пользователя должен быть свой уникальный ключ санкционирования доступа. Таким образом, при установке файла cookie значение устанавливается на ключ санкционирования доступа. После этого происходит сравнение значения ключа санкционирования доступа со значением в списке MySQL, которое вы добавите. Давайте посмотрим, как изменится функция входа пользователей в систему.
Теперь происходит проверка, прошёл ли параметр “true” через параметр запоминания функции входа в систему. Если да, для ключа санкционирования доступа задаётся файл cookie. Функция Rand_string создаёт цепочку с числом символов, которые прошли через неё. Функция Session_encrypt добавляет в цепочку произвольные данные и зашифровывает всю информацию с помощью md5. Данная цепочка является уникальной, так как в ней используется имя пользователя, которое уникально для каждого пользователя. Затем ключ санкционирования доступа в списке mysql устанавливается к значению, вводимому в файл cookie. Как бы там ни было, этой защиты может быть не достаточно для вашего сайта. Рассмотрите возможность добавления нескольких ключей санкционирования доступа и нескольких файлов cookie. Опять-таки, данная функция не соответствует требованиям функции “remember me”. Также необходимо добавить функцию инициализации.
К данной функции необходимо обращаться на каждой странице. Её назначение - проверка ключа санкционирования доступа файла cookie (“auth_key”). Если файл cookie использует функцию isset, появится соответствующий пользователь. Ещё раз, к данной функции необходимо обращаться на каждой странице.
Данный код проверяет, используется ли функция isset. Если данная функция используется файлом cookie, произойдёт проверка соответствия ключа санкционирования доступа с пользователем. Если соответствие установлено, файл извлечёт требуемую информацию и зарегистрирует пользователя. В противном случае файл cookie будет удалён, так как является недействительным.
Другие функции
Функция выхода из системы не требует разъяснений. Данная функция удаляет все переменные сессии и файлы cookie и устанавливает значение ключа санкционирования доступа для пользователя на 0. После этого ключом санкционирования доступа воспользоваться будет нельзя. Необходимо отметить, что пользователь может задать значение 0 для своего файла cookie и всё ещё регистрироваться в системе под своим именем. Чтобы это исправить, проверьте всё информацию, получаемую из файлов cookie. Используя функцию regexp, убедитесь, что цепочка содержит действительное количество символов, содержит действительные символы и т. д. Функция keepalive() поддерживает активность сессии. Данная функция должна быть на каждой странице.
Заключение & перехват сессии
Чрезвычайно сложно защититься от перехвата сессии Session Hijacking. Возможно, вы читали некоторые советы по использованию комбинации IP-адреса пользователя или процесса User Agent для создания идентификационных меток. Впрочем, это не эффективно для ваших фактических пользователей. IP-адреса пользователей постоянно меняются. У крупных поставщиков услуг Интернета, таких как AOL, они меняются каждые несколько минут. Это создаст огромную проблему. Процессы User Agent также меняются — установлено, что в IE7 агенты пользователя периодически меняются. Самый лучший способ защиты от перехвата – создать жезловую систему. Данная система выводит файл cookie на каждую страницу загрузки и также хранит это значение в вашем списке mysql. Затем происходит сравнение значения файла cookie со значением таблицы MySQL. Если они разные, сессия будет недействительной.
Это основные функции по работе с файлами сессий и файлами cookie. Разумеется, для усовершенствования защиты необходимо добавить больше файлов cookie для проверки достоверности данных. Данного уровня защиты не достаточно для защиты сугубо важной информации, но с чего-то нужно начинать! И в завершение:
Следите за тем, чтобы значения файлов cookie были действительными. Никогда не выводите пароль на сессию или переменную cookie. Для предотвращения фиксации сессии используйте идентификатор session_regenerate_id.