Cookie сессии PHP 7.3: задаём параметры до session_start

2 мин чтения

Настраиваем Secure, HttpOnly и SameSite для сессии PHP 7.3 и проверяем реальный Set-Cookie в браузере.

Параметры задаются до старта сессии
  1. Настройки cookieВыбираем Secure, HttpOnly и SameSite
  2. session_startОткрываем сессию с этими параметрами
  3. Заголовок ответаПроверяем фактический Set-Cookie

Браузер передаёт идентификатор сессии, а PHP по нему находит серверное состояние пользователя. От настроек cookie зависит, куда браузер отправит этот идентификатор и смогут ли прочитать его сценарии страницы. В PHP 7.3 параметры можно передать массивом. Сделаем это до session_start и посмотрим на заголовок ответа.

Настройки одной точки входа

<?php
ini_set('session.use_strict_mode', '1');
session_set_cookie_params([
    'lifetime' => 0,
    'path' => '/',
    'secure' => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);
session_start();
$_SESSION['view_count'] = ($_SESSION['view_count'] ?? 0) + 1;
echo (int) $_SESSION['view_count'];

Secure ограничивает передачу cookie защищённым соединением. HttpOnly закрывает доступ к нему через обычный JavaScript-интерфейс document.cookie. Значение Lax уменьшает передачу cookie при некоторых межсайтовых запросах, сохраняя распространённый сценарий перехода по внешней ссылке. Lifetime равный нулю задаёт сессионный cookie, но фактическое восстановление браузерной сессии зависит от поведения клиента. Эти флаги описывают разные свойства, поэтому один не служит заменой другому.

Настройки не равны полной защите

SameSite в браузерах 2019 года поддерживается неодинаково; приложение не должно считать его единственным средством против подделки запросов. Для действий, изменяющих данные, по-прежнему нужна согласованная защита, например серверная проверка токена. HttpOnly не исправляет уязвимость внедрения сценариев: вредоносный код может выполнять запросы от лица открытой страницы, даже если не читает идентификатор напрямую. После успешного входа отдельно продумайте смену идентификатора сессии.

Вызывать настройку нужно при каждом запросе до session_start и до отправки содержимого. Если приложение включает общий загрузочный файл, разместите настройку там и проверьте, что другой код не запускает сессию раньше. Не задавайте широкий domain без необходимости: это расширяет круг поддоменов, связанных с cookie. На локальном HTTP-стенде Secure помешает обычной передаче; используйте подходящее защищённое тестовое окружение, а не меняйте рабочую политику молча.

Проверяем в браузере

В панели сети найдите Set-Cookie и проверьте Secure, HttpOnly, SameSite и путь. Перезагрузите страницу: счётчик должен продолжить ту же сессию. Затем используйте другой профиль и переход с внешней страницы. Загляните и в журнал PHP — предупреждение о заголовках поможет заметить слишком поздний session_start.

Источники и дальнейшее чтение