Вопрос

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

Это было полезно?

Решение

Чтобы обеспечить безопасность сеанса, необходимо выполнить несколько действий:

  1. Используйте SSL при аутентификации пользователей или выполнении конфиденциальных операций.
  2. Повторно генерировать идентификатор сеанса при каждом изменении уровня безопасности (например, при входе в систему).Если хотите, вы даже можете восстанавливать идентификатор сеанса при каждом запросе.
  3. Тайм-аут сеансов
  4. Не используйте глобальные переменные регистрации
  5. Сохраните данные аутентификации на сервере.То есть не отправляйте такие данные, как имя пользователя, в файл cookie.
  6. Проверить $_SERVER['HTTP_USER_AGENT'].Это добавляет небольшой барьер для перехвата сеанса.Вы также можете проверить IP-адрес.Но это вызывает проблемы у пользователей, у которых меняется IP-адрес из-за балансировки нагрузки на нескольких интернет-соединениях и т. д. (что и имеет место в нашей среде).
  7. Заблокируйте доступ к сеансам в файловой системе или используйте собственную обработку сеансов.
  8. Для конфиденциальных операций рассмотрите возможность потребовать от вошедших в систему пользователей еще раз предоставить свои данные для аутентификации.

Другие советы

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

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

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

На эту тему есть небольшая, но хорошая книжка: «Основная безопасность PHP», Крис Шифлетт.

Основная безопасность PHP 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 (с тех пор они это исправили), но я думаю, что это все еще хорошая идея.

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

Вот хороший руководство в setTimer() иclearTimer().

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

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

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

Я настраиваю свои сеансы следующим образом:

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

$_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

Я бы проверил IP и пользовательский агент, чтобы узнать, меняются ли они.

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 за примерами обработчика сеанса базы данных.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top