Безопасность сеанса PHP

Каковы некоторые рекомендации по обеспечению безопасности ответственного сеанса с помощью PHP? Там информация по всему Интернету и о времени все это приземлилось в одном месте!

Ответ 1

Есть несколько вещей, чтобы сделать ваш сеанс безопасным:

  • Используйте SSL при аутентификации пользователей или выполнении чувствительных операций.
  • Восстановить идентификатор сеанса всякий раз, когда уровень безопасности изменяется (например, вход в систему). Вы можете даже восстановить идентификатор сеанса каждый запрос, если хотите.
  • Время ожидания сеанса
  • Не использовать глобальные регистры
  • Сохранять данные аутентификации на сервере. То есть, не отправляйте такие детали, как имя пользователя в файле cookie.
  • Проверьте $_SERVER['HTTP_USER_AGENT']. Это добавляет небольшой барьер для захвата сессии. Вы также можете проверить IP-адрес. Но это создает проблемы для пользователей, которые меняют IP-адрес из-за балансировки нагрузки на несколько интернет-соединений и т.д. (Что имеет место в нашей среде здесь).
  • Блокировать доступ к сеансам в файловой системе или использовать пользовательскую обработку сеанса
  • Для чувствительных операций подумайте о необходимости повторного входа в систему, чтобы предоставить свои данные аутентификации

Ответ 2

Одна рекомендация - называть session_regenerate_id каждый раз, когда изменяется уровень безопасности сеанса. Это помогает предотвратить захват сеанса.

Ответ 3

Я думаю, что одна из основных проблем (которая рассматривается в 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');

Ответ 4

Мои два (или более) цента:

  • Не доверяй никому
  • Вход фильтра, выход выхода (cookie, данные сеанса также являются вашим вводом)
  • Избегайте XSS (хорошо сохраняйте свой HTML-код, посмотрите PHPTAL или HTMLPurifier)
  • Глубокая защита
  • Не выставлять данные

Есть крошечная, но хорошая книга по этой теме: Основная безопасность PHP Крисом Шифлеттом.

Основная безопасность PHP http://shiflett.org/images/essential-php-security-small.png

На домашней странице книги вы найдете несколько интересных примеров кода и примеры разделов.

Вы можете использовать технику, упомянутую выше (IP и UserAgent), описанную здесь: Как избежать кражи личных данных

Ответ 6

Использование IP-адреса на самом деле не самая лучшая идея в моем опыте. Например; мой офис имеет два IP-адреса, которые используются в зависимости от нагрузки, и мы постоянно сталкиваемся с проблемами с использованием IP-адресов.

Вместо этого я решил сохранить сеансы в отдельной базе данных для доменов на моих серверах. Таким образом, никто из файловой системы не имеет доступа к этой информации о сеансе. Это было действительно полезно с phpBB до 3.0 (с тех пор они исправили это), но это все еще хорошая идея, я думаю.

Ответ 7

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

Вот хороший учебник на setTimer() и clearTimer().

Ответ 8

Основная проблема с сеансами PHP и безопасностью (помимо захвата сеанса) заключается в том, в какой среде вы находитесь. По умолчанию PHP хранит данные сеанса в файле в каталоге temp OS. Без какой-либо особой мысли или планирования это общедоступный для чтения каталог, поэтому вся ваша информация о сеансе является общедоступной для всех, у кого есть доступ к серверу.

Как для обслуживания сеансов на нескольких серверах. В этот момент было бы лучше переключить PHP на сеансы, обработанные пользователем, где он вызывает ваши предоставленные функции для CRUD (создания, чтения, обновления, удаления) данных сеанса. В этот момент вы можете сохранить информацию о сеансе в базе данных или решении типа memcache, чтобы все серверы приложений имели доступ к данным.

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

Ответ 9

Я установил свои сеансы так:

на странице входа в систему:

$_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();     
}

Ответ 10

php.ini

session.cookie_httponly = 1
change session name from default PHPSESSID

eq Apache add header:

X-XSS-Protection    1

Ответ 11

Я бы проверил как IP, так и User Agent, чтобы увидеть, изменяют ли они

if ($_SESSION['user_agent'] != $_SERVER['HTTP_USER_AGENT']
    || $_SESSION['user_ip'] != $_SERVER['REMOTE_ADDR'])
{
    //Something fishy is going on here?
}

Ответ 12

Если вы используете session_set_save_handler(), вы можете установить свой собственный обработчик сеанса. Например, вы можете хранить свои сессии в базе данных. Обратитесь к комментариям php.net для примеров обработчика сеанса базы данных.

Службы DB также хороши, если у вас несколько серверов, если вы используете сеансы на основе файлов, вам нужно убедиться, что каждый веб-сервер имеет доступ к одной и той же файловой системе для чтения/записи сеансов.

Ответ 13

Вы должны быть уверены, что данные сеанса безопасны. Просмотрев ваш 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, чтобы set и альтернативный обработчик сеанса.