PHP Session Security
Каковы некоторые рекомендации по поддержанию ответственной безопасности сеанса с помощью PHP? В Интернете есть информация, и пришло время приземлиться в одном месте!
13 ответов
Есть несколько вещей, чтобы сохранить ваш сеанс в безопасности:
- Используйте SSL при аутентификации пользователей или выполнении конфиденциальных операций.
- Регенерируйте идентификатор сеанса всякий раз, когда изменяется уровень безопасности (например, вход в систему). Вы можете даже восстановить идентификатор сессии каждый запрос, если хотите.
- Время сессий
- Не используйте регистр глобалов
- Храните данные аутентификации на сервере. То есть не отправляйте такие данные, как имя пользователя, в cookie.
- Проверить
$_SERVER['HTTP_USER_AGENT']
, Это добавляет небольшой барьер для захвата сессии. Вы также можете проверить IP-адрес. Но это вызывает проблемы у пользователей, которые меняют IP-адрес из-за балансировки нагрузки на несколько интернет-соединений и т. Д. (Что имеет место в нашей среде здесь). - Заблокируйте доступ к сеансам в файловой системе или используйте пользовательскую обработку сеансов
- Для чувствительных операций рассмотрите требование, чтобы вошедшие в систему пользователи снова предоставили свои данные аутентификации.
Одно из правил - вызывать http://www.php.net/session_regenerate_id каждый раз, когда изменяется уровень безопасности сеанса. Это помогает предотвратить угон сеанса.
Мои два (или более) цента:
- Не доверять никому
- Фильтр ввода, экранирование вывода (cookie, данные сеанса также являются вашими данными)
- Избегайте XSS (держите ваш HTML правильно, посмотрите на PHPTAL или HTMLPurifier)
- Глубокая защита
- Не подвергайте данные
На эту тему есть небольшая, но хорошая книга: Essential PHP Security от Chris Shiflett.
http://shiflett.org/images/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 (они с тех пор исправили это), но я думаю, что это все еще хорошая идея.
Это довольно тривиально и очевидно, но обязательно используйте http://www.php.net/session_destroy после каждого использования. Это может быть трудно реализовать, если пользователь явно не выходит из системы, поэтому для этого можно установить таймер.
Вот хороший учебник по setTimer() и clearTimer().
Я настроил свои сессии так
на странице входа в систему:
$_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();
}
php.ini
session.cookie_httponly = 1
change session name from default PHPSESSID
eq Apache добавить заголовок:
X-XSS-Protection 1
Основная проблема с PHP-сессиями и безопасностью (помимо перехвата сессий) связана с тем, в какой среде вы находитесь. По умолчанию PHP сохраняет данные сессий в файле во временном каталоге ОС. Без какого-либо особого размышления или планирования, это общедоступный каталог, поэтому вся информация о вашем сеансе доступна для всех, кто имеет доступ к серверу.
Что касается ведения сеансов на нескольких серверах. В этот момент было бы лучше переключить PHP на пользовательские сеансы, где он вызывает предоставленные вами функции для CRUD (создание, чтение, обновление, удаление) данных сеанса. В этот момент вы можете хранить информацию о сеансе в базе данных или в виде решения, подобного memcache, чтобы все серверы приложений имели доступ к данным.
Хранение ваших собственных сессий также может быть полезным, если вы находитесь на общем сервере, потому что это позволит вам сохранить его в базе данных, которую вы часто имеете больший контроль над файловой системой.
Вы должны быть уверены, что данные сеанса в безопасности. Посмотрев на свой 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()_ .
Посмотрите учебник Криса Шифлетта или Zend_Session_SaveHandler_DbTable для установки и альтернативного обработчика сеанса.
Если вы используете session_set_save_handler(), вы можете установить свой собственный обработчик сессии. Например, вы можете хранить ваши сессии в базе данных. Обратитесь к комментариям php.net за примерами обработчика сеанса базы данных.
Сеансы БД также хороши, если у вас несколько серверов, в противном случае, если вы используете файловые сеансы, вам необходимо убедиться, что каждый веб-сервер имеет доступ к одной и той же файловой системе для чтения / записи сеансов.
Я бы проверил IP и User Agent, чтобы увидеть, если они меняются
if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
|| $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
//Something fishy is going on here?
}