Каковы некоторые рекомендации по обеспечению ответственной безопасности сеанса с помощью PHP? Там есть информация по всему Интернету, и пришло время, когда все приземлилось в одном месте!
Есть несколько вещей, чтобы сделать вашу сессию безопасной:
$_SERVER['HTTP_USER_AGENT']
. Это добавляет небольшой барьер для захвата сессии. Вы также можете проверить IP-адрес. Но это создает проблемы для пользователей, которые меняют IP-адрес из-за балансировки нагрузки на несколько интернет-соединений и т. Д. (Что имеет место в нашей среде здесь). Одна из рекомендаций – вызывать session_regenerate_id каждый раз, когда уровень безопасности сеанса изменяется. Это помогает предотвратить захват сеанса.
Мои две (или более) центов:
Существует крошечная, но хорошая книга по этой теме: « Основная безопасность PHP» Криса Шифлетта .
Основная безопасность PHP http://img.ruphp.com/security/essential-php-security-small.png
На домашней странице книги вы найдете несколько интересных примеров кода и примеры разделов.
Вы можете использовать технику, упомянутую выше (IP & UserAgent), описанную здесь: Как избежать кражи личных данных
Я думаю, что одна из основных проблем (которая рассматривается в PHP 6) – register_globals. В настоящее время одним из стандартных методов, используемых для исключения register_globals
является использование массивов $_REQUEST
, $_GET
или $_POST
.
«Правильный» способ сделать это (начиная с 5.2, хотя он немного глючит, но стабильный с 6, который скоро появится) проходит через фильтры .
Поэтому вместо:
$username = $_POST["username"];
вы бы сделали:
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
или даже просто:
$username = filter_input(INPUT_POST, 'username');
Эта документация фиксации сеанса имеет очень хорошие указания, где может наступить атака. См. Также страницу фиксации сеанса в Википедии .
Использование IP-адреса на самом деле не самая лучшая идея в моем опыте. Например; мой офис имеет два IP-адреса, которые используются в зависимости от нагрузки, и мы постоянно сталкиваемся с проблемами с использованием IP-адресов.
Вместо этого я решил сохранить сеансы в отдельной базе данных для доменов на моих серверах. Таким образом, никто из файловой системы не имеет доступа к этой информации о сеансе. Это было действительно полезно с phpBB до 3.0 (с тех пор они исправили это), но это все еще хорошая идея, я думаю.
Это довольно тривиально и очевидно, но обязательно проверяйте session_destroy после каждого использования. Это может быть сложно реализовать, если пользователь не выходит из системы явно, поэтому для этого можно установить таймер.
Вот хороший учебник по setTimer () и clearTimer ().
Основная проблема с сеансами PHP и безопасностью (помимо захвата сеанса) заключается в том, в какой среде вы находитесь. По умолчанию PHP хранит данные сеанса в файле в каталоге temp OS. Без какой-либо особой мысли или планирования это общедоступный для чтения каталог, поэтому вся ваша информация о сеансе является общедоступной для всех, у кого есть доступ к серверу.
Что касается поддержки сеансов на нескольких серверах. В этот момент было бы лучше переключить PHP на сеансы, обработанные пользователем, где он вызывает ваши предоставленные функции для CRUD (создания, чтения, обновления, удаления) данных сеанса. В этот момент вы можете сохранить информацию о сеансе в базе данных или решении типа memcache, чтобы все серверы приложений имели доступ к данным.
Сохранение ваших собственных сеансов также может быть выгодным, если вы находитесь на общем сервере, потому что он позволит вам сохранить его в базе данных, которую вы часто чаще контролируете файловой системой.
Я поставил свои сеансы так:
на странице входа:
$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR']);
(фраза, определенная на странице конфигурации)
затем в заголовке, который находится на всем остальном сайте:
session_start(); if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . PHRASE . $_SERVER['REMOTE_ADDR'])) { session_destroy(); header('Location: http://website login page/'); exit(); }
session.cookie_httponly = 1 change session name from default PHPSESSID
X-XSS-Protection 1
Я бы проверил как IP, так и User Agent, чтобы узнать, меняются ли они
if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT'] || $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR']) { //Something fishy is going on here? }
Если вы используете session_set_save_handler (), вы можете установить собственный обработчик сеанса. Например, вы можете хранить свои сессии в базе данных. Обратитесь к комментариям php.net для примеров обработчика сеанса базы данных.
Службы DB также хороши, если у вас несколько серверов, если вы используете сеансы на основе файлов, вам нужно убедиться, что каждый веб-сервер имеет доступ к одной и той же файловой системе для чтения / записи сеансов.
Вы должны быть уверены, что данные сеанса безопасны. Просмотрев ваш php.ini или используя phpinfo (), вы можете найти настройки сеанса. _session.save_path_ сообщает вам, где они сохранены.
Проверьте разрешение папки и ее родителей. Он не должен быть общедоступным (/ tmp) или доступен другим веб-сайтам на вашем общем сервере.
Предполагая, что вы все еще хотите использовать php-сессию, вы можете настроить php на использование другой папки, изменив _session.save_path_ или сохраните данные в базе данных, изменив _session.save_handler_.
Возможно, вы установили _session.save_path_ в php.ini (некоторые провайдеры разрешили его) или для apache + mod_php в файле .htaccess в корневой папке вашего сайта: php_value session.save_path "/home/example.com/html/session"
. Вы также можете установить его во время выполнения с помощью _session_save_path () _.
Проверьте учебник Chris Shiflett или Zend_Session_SaveHandler_DbTable для установки и альтернативного обработчика сеанса.