mirror of
https://github.com/php/doc-ru.git
synced 2025-07-22 18:26:31 +00:00
788 lines
49 KiB
XML
788 lines
49 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
||
<!-- EN-Revision: 418de4470840c212677d03adb64c372f77fdf510 Maintainer: rjhdby Status: ready -->
|
||
<!-- Reviewed: yes Maintainer: rjhdby -->
|
||
<!-- $Revision$ -->
|
||
|
||
<chapter xml:id="session.security" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||
<title>Безопасность сессий</title>
|
||
<para>
|
||
Внешние ссылки: <link xlink:href="&url.session-fixation;">Атака "Фиксация сессии"</link>
|
||
</para>
|
||
<para>
|
||
Работа с HTTP-сессиями является основой веб-безопасности. Должны быть применены
|
||
все возможные меры для обеспечения безопасности сессии. Разработчик должен включать и
|
||
использовать соответствующие настройки соответствующим образом.
|
||
</para>
|
||
|
||
<sect1 xml:id="features.session.security.management">
|
||
<title>Базовые принципы управления сессиями</title>
|
||
|
||
<sect2 xml:id="features.session.security.management.basic">
|
||
<title>Безопасность сессии</title>
|
||
|
||
<para>
|
||
Модуль сессии не гарантирует, что хранимая сессионная информация доступна
|
||
только пользователю, который создал сессию. Необходимо принять дополнительные
|
||
меры по защите конфиденциальности сессии, основываясь на связанных с ней данных.
|
||
</para>
|
||
|
||
<para>
|
||
Оценка важности данных, передаваемых в рамках сессии, важна для выбора мер по
|
||
защите этой информации; все имеет свою цену и обычно дополнительные меры защиты
|
||
приводят к ухудшению удобства для конечного пользователя.
|
||
Например, если необходимо защитить пользователя от
|
||
простейших методов социальной инженерии, следует включить
|
||
<literal>session.use_only_cookies</literal>. В данном случае со стороны
|
||
пользовательского ПО обязательна поддержка cookie, иначе механизм сессий не
|
||
будет работать.
|
||
</para>
|
||
|
||
<para>
|
||
Существует несколько способов утечки существующего идентификатора сессии
|
||
третьим лицам. Например инъекции JavaScript, передача идентификатора
|
||
сесии в URL, перехват пакетов, физический доступ к устройству и т.д.
|
||
Перехваченный идентификатор сессии позволит третьим лицам получить
|
||
доступ ко всем ресурсам, связанным с данной сессией. Во-первых,
|
||
передача идентификатора сессии в URL. При переходе на внешний сайт
|
||
идентификатор сессии пользователя и адрес ресурса могут попасть в статистику
|
||
переходов данного сайта. Во-вторых, при более активной атаке возможно
|
||
прослушивание сетевого трафика злоумышленником. Если канал передачи данных не
|
||
зашифрован, идентификаторы сессии будут переданы в виде простого текста. В
|
||
таком случае решением является обязательное использование SSL/TLS пользователями
|
||
при доступе к сайту. Для этих целей следует применять HSTS.
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
Даже HTTPS иногда может не защитить конфиденциальные данные. Например,
|
||
уязвимости типа CRIME, BEAST могут позволить злоумышленнику получить доступ к
|
||
данным. Многие сети используют прокси HTTPS MITM
|
||
для аудита. Атакующие также могут настроить такие прокси.
|
||
</simpara>
|
||
</note>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="features.session.security.management.non-adaptive-session">
|
||
<title>Неадаптивное управление сессиями</title>
|
||
|
||
<para>
|
||
В настоящее время PHP использует адаптивное управление сессиями по умолчанию.
|
||
Адаптивное управление сессиями несет дополнительные риски.
|
||
</para>
|
||
|
||
<para>
|
||
С версии PHP 5.5.2 доступна опция
|
||
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>.
|
||
При её включении и при условии, что обработчик сохранения сессий её поддерживает,
|
||
неинициализированный сессионный ID отвергается и создается новый.
|
||
Это защищает от атак, которые принуждают пользователя использовать
|
||
заранее извесный ID. Ататкующий может размещать ссылки или отправлять письма,
|
||
которые содержат сессионный ID. Например http://example.com/page.php?PHPSESSID=123456789 .
|
||
Если опция <link linkend="ini.session.use-trans-sid">session.use_trans_sid</link> включена, то
|
||
жертва откроет сессию с этим идентификатором.
|
||
Опция <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link> уменьшает этот риск.
|
||
</para>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Определённый пользователем обработчик сохранения также может поддерживать
|
||
строгий сессионный режим, путем реализации функции/метода проверки корректности
|
||
идентификатора сессии. Все определённые пользователем обработчики сохранения
|
||
обязаны его реализовывать.
|
||
</simpara>
|
||
</warning>
|
||
|
||
<para>
|
||
Cookie с сессионным ID должна устанавливаться с указанием параметров domain, path,
|
||
httponly, secure и, начиная с PHP 7.3, аттрибут SameSite.
|
||
<!-- Not exactly sure what the meaning here is - girgias -->
|
||
Их приоритетность определяется браузерами.
|
||
Опираясь на эту приоритетность, атакующий может может установить сессионный ID, который
|
||
будет использоваться бесконечно. Применение <link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
||
не решает эту проблему. <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
||
уменьшает риск. <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On,
|
||
не допускает использование неинициализированных сессионных ID.
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
Даже при уменьшении риска с помощью <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
||
атакующий все ещё может заставить пользователя использовать
|
||
уже инициализированную сессию, созданную атакующим. Например JavaScript-инъекция.
|
||
Эта атака может быть смягчена, если следовать рекомендациям этого руководства.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Если вы следуете этому руководству, вы должны включить <link
|
||
linkend="ini.session.use-strict-mode">session.use_strict_mode</link>,
|
||
использовать управление сессиями на основе временных меток и
|
||
пересоздавать идентификатор сессии с помощью <function>session_regenerate_id</function>,
|
||
как рекомендуется. Если вы всё это сделаете, идентификатор сессии
|
||
злоумышленника в итоге будет удален.
|
||
</simpara>
|
||
|
||
<simpara>
|
||
Если произошел доступ к истекшей сессией, вы должны сохранить все
|
||
данные активных сессий пользователя. Это позволит для дальнейшего
|
||
расследования причин произошедшего. После этого, принудительно
|
||
заставьте пользователя выйти из всех активных сессий, то есть потребуйте от
|
||
пользователей переавторизации. Это позволит предотвратить
|
||
атаку с использованием краденной сессии.
|
||
</simpara>
|
||
</note>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Доступ к истекшей сессии не всегда означает атаку.
|
||
Нестабильное сетевое соединение и/или немедленное удаление
|
||
активной сессии может повлечь за собой подобное поведение.
|
||
</simpara>
|
||
</warning>
|
||
|
||
<para>
|
||
С PHP 7.1.0 добавлена функция <function>session_create_id</function>.
|
||
Эта функция может быть полезна для создания идентификатора сессии с
|
||
использованием идентификатора пользователя в качестве префикса
|
||
для достижения большей управляемости. При её использовании крайне важно
|
||
разрешать <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>.
|
||
В противном случае недобросовестные пользователи смогут устанавливать поддельные
|
||
идентификаторы сессий для других пользователей.
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
В версиях PHP до 7.1.0 необходимо использовать CSPRNG, то есть /dev/urandom или
|
||
<function>random_bytes</function> и функции хеширования для генерации
|
||
нового идентификатора сессии. <function>session_create_id</function> имеет
|
||
встроенный функционал обнаружения коллизий и генерирует идентификатор
|
||
основываясь на INI-настройках. Использование <function>session_create_id</function>
|
||
является предпочтительной практикой.
|
||
</simpara>
|
||
</note>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="features.session.security.management.session-id-regeneration">
|
||
<title>Пересоздание идентификатора сессии</title>
|
||
|
||
<para>
|
||
Использование <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>
|
||
- это хорошо, но недостаточно. Разработчик также должен использовать
|
||
<function>session_regenerate_id</function> для обеспечения безопасности сессий.
|
||
</para>
|
||
|
||
<para>
|
||
Пересоздание идентификаторов сессий сильно уменьшает риск кражи сессии,
|
||
соответственно надо на переодической основе запускать
|
||
<function>session_regenerate_id</function>. Например, пересоздавать идентификатор сессии
|
||
каждые 15 минут для особо секретных данных. Даже если сессию украдут,
|
||
она достаточно скоро станет истекшей и попытка её использовать
|
||
приведет к ошибке истекшей сессии.
|
||
</para>
|
||
|
||
<para>
|
||
Идентификатор сессии <emphasis>должен</emphasis> пересоздаваться при
|
||
повышении привилегий пользователя, например при аутентификации.
|
||
Функция <function>session_regenerate_id</function> должна вызываться до записи
|
||
авторизационной информации в $_SESSION. (В PHP 7.0.0,
|
||
<function>session_regenerate_id</function> сохраняет данные текущей сессии
|
||
автоматически). Убедитесь, что только текущая сессия отмечена как
|
||
авторизованная.
|
||
</para>
|
||
|
||
<para>
|
||
Разработчики <emphasis>НЕ ДОЛЖНЫ</emphasis> полагаться на механизм истечения срока действия
|
||
идентификатора сессии с помощью <link
|
||
linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>.
|
||
Атакующие могут периодически получать доступ к сессии для
|
||
предотвращения её срока действия и продолжать использовать идентификатор жертвы,
|
||
включая аутентифицированные сессии.
|
||
</para>
|
||
|
||
<para>
|
||
Вместо этого, вы должны самостоятельно реализовать управление данными сессии
|
||
базируясь на временной метке.
|
||
</para>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Несмотря на то, что менеджер сессий может прозрачно управлять
|
||
временными метками, этот функционал не реализован. Данные
|
||
старых сессий сохраняются до момента запуска сборщика мусора.
|
||
В то же время, разработчики должны убедиться, что данные
|
||
истекших сессий удалены. Однако разработчики НЕ должны удалять данные активных сессий немедленно.
|
||
Например, никогда не вызывайте <literal>session_regenerate_id(true);</literal>
|
||
и <function> session_destroy</function> совместно для активных сессий.
|
||
Это может показаться противоречивым, но это обязательное требование.
|
||
</simpara>
|
||
</warning>
|
||
|
||
<para>
|
||
<function>session_regenerate_id</function> по умолчанию <emphasis>не</emphasis>
|
||
удаляет старые сессии. Устаревшие авторизованные сессии могут быть доступны
|
||
для использования. Разработчики должны пресечь любую возможность
|
||
использования старых сессий кем-либо, запретив доступ
|
||
к истекшим сессиям самостоятельно, используя временные метки.
|
||
</para>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Немедленное удаление активных сессий может повлечь нежелательные
|
||
побочные эффекты. Сессия может прерваться из-за нестабильности
|
||
сети или конкурентного доступа к сайту/приложению.
|
||
</simpara>
|
||
<simpara>
|
||
Потенциальный недобросовестный доступ будет невозможно отследить и
|
||
проанализировать, если данные сессий будут немедленно удаляться.
|
||
</simpara>
|
||
<simpara>
|
||
Вместо немедленного удаления старых сессий вы должны сохранять их
|
||
непродолжительное время, например, установив специальный флаг и
|
||
время окончательного истечения сессии в $_SESSION, запретив
|
||
кому-либо обращаться к этим данным.
|
||
</simpara>
|
||
<simpara>
|
||
Вы не должны запрещать доступ к старым сессиям сразу же после вызова
|
||
<function>session_regenerate_id</function>. Необходимо подождать несколько
|
||
секунд для стабильных сетевых соединений и несколько минут для нестабильных,
|
||
например для WiFi или мобильного интернета.
|
||
</simpara>
|
||
<simpara>
|
||
Если пользователь пытается получить доступ к истекшей сессии, вы не должны
|
||
его предоставлять. В этом случае рекомендуется удалять статус "авторизован"
|
||
со всех активных сессий пользователя, поскольку это очень похоже на атаку.
|
||
</simpara>
|
||
</warning>
|
||
|
||
<para>
|
||
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>
|
||
и правильное использование <function>session_regenerate_id</function> могут
|
||
привести к персональной DoS посредством установки неудаляемой cookie.
|
||
Если такое происходит, то вы можете попросить
|
||
пользователя удалить cookie и предупредить его о возможных проблемах
|
||
с безопасностью. Атакующий может устанавливать вредные cookie через уязвимость
|
||
в веб-приложении (то есть JavaScript-инъекция), уязвимость в браузерном плагине и т.д.
|
||
</para>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Не недооценивайте риск DoS. <literal>use_strict_mode=On</literal>
|
||
обязателен для общей безопасности идентификаторов сессий!
|
||
Все сайты должны использовать <literal>use_strict_mode</literal>.
|
||
</simpara>
|
||
<simpara>
|
||
DoS (отказ в обслуживании) может произойти только тогда, когда аккаунт
|
||
находится под атакой. Наиболее частая предпосылка для него
|
||
- JavaScript-инъекция.
|
||
</simpara>
|
||
</warning>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="features.session.security.management.session-data-deletion">
|
||
<title>Удаление данных сессии</title>
|
||
|
||
<para>
|
||
Данные истекших сессий должны быть недоступны и удалены. Существующий
|
||
механизм управления сессиями делает это не очень хорошо.
|
||
</para>
|
||
|
||
<para>
|
||
Данные истекших сессий надо удалять так быстро, как только возможно.
|
||
С другой стороны, данные активных сессий НЕ ДОЛЖНЫ удаляться сразу же.
|
||
Для обеспечения этих противоречивых требований, вы ДОЛЖНЫ самостоятельно
|
||
реализовать механизм контроля за истекшими сессиями на базе
|
||
временных меток.
|
||
</para>
|
||
|
||
<para>
|
||
Устанавливайте и управляйте временными метками жизни сессии через $_SESSION.
|
||
Запрещайте доступ к данным истекших сессий. Если обнаружена попытка доступа
|
||
к данным устаревшей сессии, снимайте статус авторизации со всех активных
|
||
сессий пользователя и вынуждайте его переавторизоваться. Доступ к данным
|
||
истекшей сессии может означать атаку. Для обеспечения такого поведения
|
||
вы должны отслеживать все активные сессии пользователя.
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
Доступ к истекшей сессии может также произойти из-за нестабильного
|
||
сетевого доступа и/или конкурентного доступа к приложению/сайту.
|
||
Сервер может попытаться установить новый идентификатор сессии через
|
||
cookie, но пакет "Set-Cookie" может не дойти до клиента из-за плохой связи.
|
||
Одно соединение может вызвать пересоздание идентификатора посредством
|
||
<function>session_regenerate_id</function>, а другое, в то же время,
|
||
может не получить нового идентификатора.
|
||
Следовательно, вы должны запретить доступ к истекшим сессиям чуть-чуть позже.
|
||
То есть управление сессиями на базе временных меток является обязательным.
|
||
</simpara>
|
||
</note>
|
||
|
||
<para>
|
||
Короче говоря, не уничтожайте данные сессии ни с помощью <function>session_regenerate_id</function>,
|
||
ни <function>session_destroy</function>, а используйте механизм
|
||
доступа к сессии на базе временных меток. Пусть <function>session_gc</function>
|
||
сам удаляет старые сессии из хранилища.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="features.session.security.management.session-locking">
|
||
<title>Сессии и блокировки</title>
|
||
|
||
<para>
|
||
По умолчанию данные сессии заблокированы, чтобы избежать состояния гонки.
|
||
Блокировка обязательна для обеспечения консистентности данных сессии между
|
||
запросами.
|
||
</para>
|
||
|
||
<para>
|
||
Однако блокировка может быть использована атакующим для организации DoS-атаки.
|
||
Для уменьшения риска DoS с использованием блокировки сессий, минимизируйте их.
|
||
Используйте блокировку "read only", когда сессию не нужно обновлять.
|
||
Используйте опцию 'read_and_close' с <function>session_start</function>.
|
||
<literal>session_start(['read_and_close'=>1]);</literal>
|
||
Закрывайте сессию с помощью <function>session_commit</function> сразу, как только
|
||
вы закончили обновлять $_SESSION.
|
||
</para>
|
||
|
||
<para>
|
||
Текущий механизм управления сессиями <emphasis>не следит</emphasis> за изменениями
|
||
$_SESSION, пока сессия неактивна. Это ваша зона ответственности, следить
|
||
за тем, чтобы подобного не случалось.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="features.session.security.management.active-sessions">
|
||
<title>Активные сессии</title>
|
||
|
||
<para>
|
||
Разработчики должны следить за активными сессиями каждого пользователя и
|
||
оповещать его, сколько есть активных сессий, с каких IP (и где географически),
|
||
как долго они активны и т.д. PHP не сделает этого за вас. Вы должны это делать.
|
||
</para>
|
||
|
||
<para>
|
||
Есть несколько путей реализации. Вы можете хранить всю нужную информацию
|
||
в специальной базе данных. Так что, когда сессия будет удалена сборщиком мусора,
|
||
вы должны это отслеживать и соответственно обновлять свою базу данных.
|
||
</para>
|
||
|
||
<para>
|
||
Самый простой способ - использовать идентификатор пользователя в качестве префикса
|
||
для идентификатора сессии и хранить всю требуемую информацию в $_SESSION.
|
||
Многие базы данных умеют достаточно быстро выбирать строки по префиксу.
|
||
Вы можете использовать <function>session_regenerate_id</function> и
|
||
<function>session_create_id</function> для этого.
|
||
</para>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Никогда в качестве префикса не используйте конфиденциальные данные.
|
||
Если идентификатор пользователя конфиденциален, рассмотрите возможность
|
||
использовать функцию <function>hash_hmac</function>.
|
||
</simpara>
|
||
</warning>
|
||
|
||
<warning>
|
||
<simpara>
|
||
Для подобной настройки требуется включение <link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>.
|
||
Убедитесь, что эта опция включена, иначе база данных
|
||
активных сессий может быть скомпрометирована.
|
||
</simpara>
|
||
</warning>
|
||
|
||
<para>
|
||
Управление сессиями на базе временных меток является обязательным для
|
||
определения устаревших сессий. Если обнаружена попытка доступа к
|
||
устаревшей сессии, необходимо сбросить флаги авторизации для
|
||
всех активных сессий пользователя.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="features.session.security.management.session-and-autologin">
|
||
<title>Сессии и автоматический вход</title>
|
||
|
||
<para>
|
||
Разработчики НЕ ДОЛЖНЫ использовать долгоживущие сессии для реализации
|
||
автоматического входа в систему, потому что это резко повышает вероятность
|
||
кражи сессии. Автоматический вход в систему должен реализовываться
|
||
разработчиком самостоятельно.
|
||
</para>
|
||
|
||
<para>
|
||
Устанавливайте безопасные хешированные одноразовые ключи
|
||
в качестве ключей автологина с помощью <function>setcookie</function>.
|
||
Используйте безопасное хеширование, посильнее чем SHA-2, например
|
||
SHA-256 или выше со случайными данными из <function>random_bytes</function>
|
||
или /dev/urandom.
|
||
</para>
|
||
|
||
<para>
|
||
Если пользователь не авторизован, проверьте, корректен ли одноразовый
|
||
ключ автологина. Если ключ корректен, авторизуйте пользователя и
|
||
установите ему новый одноразовый ключ.
|
||
Ключ автологина обязательно должен быть одноразовым, то есть никогда
|
||
не используйте его повторно, а всегда создавайте новый.
|
||
</para>
|
||
|
||
<para>
|
||
Ключ автологина - это очень долгоживущий ключ авторизации. Его надо защищать
|
||
по максимуму. Используйте параметры path/httponly/secure/SameSite при
|
||
установке cookie для его защиты.
|
||
Никогда не передавайте ключ автологина, кроме случаев, когда это необходимо.
|
||
</para>
|
||
|
||
<para>
|
||
Разработчик должен реализовать функционал, который отключает автоматический
|
||
вход в систему и удаляет ненужные "cookie", установленные для его реализации.
|
||
</para>
|
||
|
||
</sect2>
|
||
|
||
<sect2 xml:id="features.session.security.management.csrf">
|
||
<title>CSRF (Межсайтовая подделка запроса)</title>
|
||
|
||
<para>
|
||
Сессии и авторизация не защищают от атак типа CSRF.
|
||
Разработчики должны самостоятельно реализовывать защиту.
|
||
</para>
|
||
|
||
<para>
|
||
<function>output_add_rewrite_var</function> может быть использована
|
||
для защиты от CSRF. Читайте руководство для подробностей.
|
||
</para>
|
||
|
||
<note>
|
||
<simpara>
|
||
До PHP 7.2.0 использовался один и тот же буфер вывода и INI-настройки
|
||
для "trans sid". Так что использование <function>output_add_rewrite_var</function>
|
||
с PHP более ранних версий не рекомендуется.
|
||
</simpara>
|
||
</note>
|
||
|
||
<para>
|
||
Многие фреймворки поддерживают защиту от CSRF. Обратитесь к документации
|
||
своего фреймворка для более подробной информации.
|
||
</para>
|
||
|
||
<para>
|
||
Начиная с PHP 7.3, для сессионной cookie можно установить атрибут SameSite.
|
||
Это обеспечит дополнительную защиту против CSRF.
|
||
</para>
|
||
</sect2>
|
||
</sect1>
|
||
|
||
<sect1 xml:id="session.security.ini">
|
||
<title>INI-настройки безопасности сессий</title>
|
||
|
||
<para>
|
||
Предоставляя INI-настройки, связанные с сессиями,
|
||
вы можете улучшить безопасность сессий. Некоторые важные настройки безопасности
|
||
не имеют рекомендованных значений. Вы сами ответственны за выбор необходимых значений.
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.cookie-lifetime">session.cookie_lifetime</link>=0
|
||
</para>
|
||
<para>
|
||
<literal>0</literal> имеет особое значение. Он сообщает браузеру не сохранять
|
||
cookie в постоянное хранилище. Следовательно, когда браузер закрывается,
|
||
сессионные cookie сразу же удаляются. Если задать значение отличное
|
||
от 0, это может позволить другим пользователям использовать эти cookie.
|
||
В большинстве случаев лучше всего использовать "<literal>0</literal>".
|
||
</para>
|
||
<para>
|
||
Если требуется функционал автологина, реализовывайте его самостоятельно и
|
||
никогда не используйте для этого долгоживущие сессии.
|
||
Более подробно изложено выше в соответствующих разделах.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.use-cookies">session.use_cookies</link>=On
|
||
</para>
|
||
<para>
|
||
<link linkend="ini.session.use-only-cookies">session.use_only_cookies</link>=On
|
||
</para>
|
||
<para>
|
||
Несмотря на то, что HTTP-cookie имеют некоторые проблемы, все же они
|
||
наиболее предпочтительны для хранения идентификатора сессии. Когда это
|
||
возможно, для управления идентификаторами сессий необходимо использовать
|
||
"cookie". Большинство приложений должны использовать cookie для идентификатора сессии.
|
||
</para>
|
||
<para>
|
||
Если <literal>session.use_only_cookies</literal>=Off,
|
||
модуль сессии будет использовать идентификатор, установленный
|
||
через GET/POST/URL, если "cookie" не была выставлена заранее.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.use-strict-mode">session.use_strict_mode</link>=On
|
||
</para>
|
||
<para>
|
||
Крайне рекомендуется включать
|
||
<literal>session.use_strict_mode</literal>. По умолчанию не включено.
|
||
</para>
|
||
<para>
|
||
Это не позволит сессионному модулю использовать неинициализированные
|
||
идентификаторы сессий. Другими словами, сессионный модуль будет
|
||
принимать только корректные идентификаторы, сгенерированные им же и
|
||
будет игнорировать идентификаторы созданные на стороне пользователя.
|
||
</para>
|
||
<para>
|
||
Из-за особенностей спецификации cookie, атакующий может сделать
|
||
cookie с идентификатором сессии неудаляемой с помощью локальной
|
||
базы cookie или JavaScript-инъекцией.
|
||
<literal>session.use_strict_mode</literal> может не дать
|
||
атакующему использовать этот идентификатор.
|
||
</para>
|
||
<note>
|
||
<para>
|
||
Атакующие могут инициализировать идентификатор сессии на своем устройстве
|
||
и выставить его жертве. Они должны будут поддерживать сессию в активном
|
||
состоянии для злоупотреблений. Атакующим понадобится совершить
|
||
дополнительные действия для проведения атаки по этому сценарию.
|
||
Поэтому <literal>session.use_strict_mode</literal>
|
||
служит как предотвращение этому.
|
||
</para>
|
||
</note>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.cookie-httponly">session.cookie_httponly</link>=On
|
||
</para>
|
||
<para>
|
||
Запрещает доступ к сессионной cookie для JavaScript. Эта опция
|
||
предотвращает кражу cookie с помощью JavaScript-инъекции.
|
||
</para>
|
||
<para>
|
||
Можно использовать сессионный ID как защитный ключ CSRF, но не рекомендуется.
|
||
Например, HTML может быть сохранен и отправлен другому пользователю.
|
||
Разработчик не должен записывать сессионный ID внутри страницы для повышения безопасности.
|
||
Почти все приложения должны использовать атрибут httponly для сессионной cookie.
|
||
</para>
|
||
<note>
|
||
<para>
|
||
Защитный ключ CSRF должен периодически обновляться, как и идентификатор сессии.
|
||
</para>
|
||
</note>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.cookie-secure">session.cookie_secure</link>=On
|
||
</para>
|
||
<para>
|
||
Разрешает получать доступ к cookie идентификатора сессии только при использовании протокола HTTPS.
|
||
Если ваш сайт использует только протокол HTTPS, вам необходимо включить эту опцию.
|
||
</para>
|
||
<para>
|
||
Для таких сайтов нужно также рассматривать использование HSTS.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Lax" или
|
||
<link linkend="ini.session.cookie-samesite">session.cookie_samesite</link>="Strict"
|
||
</para>
|
||
<para>
|
||
Начиная с PHP 7.3, вы можете установить cookie-флаг <literal>"SameSite"</literal> для
|
||
cookie идентификатора сессии. Этот флаг является способом смягчения атак CSRF (межсайтовая подделка запроса).
|
||
</para>
|
||
<para>
|
||
Разница между Lax и Strict заключается в доступности cookie в запросах,
|
||
исходящих из другого регистрируемого домена с использованием HTTP-метода GET.
|
||
Cookie, использующие Lax, будут доступны в GET-запросе, исходящем из другого регистрируемого домена,
|
||
тогда как cookie, использующие Strict, не будут.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.gc-maxlifetime">session.gc_maxlifetime</link>=[выбрать наименьший из возможных]
|
||
</para>
|
||
<para>
|
||
<literal>session.gc_maxlifetime</literal> настройка для удаления устаревших
|
||
идентификаторов сессий. Полагаться на эту опцию категорически
|
||
<emphasis>не</emphasis> рекомендуется.
|
||
Вы должны управлять жизненным циклом сессии самостоятельно.
|
||
</para>
|
||
<para>
|
||
Сессионный сборщик мусора GC (garbage collection) лучше использовать с помощью <function>session_gc</function>.
|
||
Функцию <function>session_gc</function> лучше всего запускать через планировщик,
|
||
например, cron на *nix-системах.
|
||
</para>
|
||
<para>
|
||
По умолчанию GC работает на вероятностном принципе. Эта настройка
|
||
<emphasis>не</emphasis> гарантирует удаление старых сессий. Разработчику не следует
|
||
полагаться на эту настройку, но все равно, рекомендуется выставить ее
|
||
минимально возможным значением. Настраивайте <link linkend="ini.session.gc-probability">session.gc_probability</link>
|
||
и <link linkend="ini.session.gc-divisor">session.gc_divisor</link> так,
|
||
чтобы устаревшие сессии удалялись достаточно часто.
|
||
Если требуется функционал автологина, реализуйте его самостоятельно и
|
||
никогда не используйте для этого долгоживущие сессии.
|
||
</para>
|
||
<note>
|
||
<para>
|
||
Некоторые обработчики сохранения сессий не используют
|
||
механизм устаревания сессий на основе вероятностей.
|
||
Например memcached, memcache. Читайте соответствующую
|
||
документацию для более полной информации.
|
||
</para>
|
||
</note>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.use-trans-sid">session.use_trans_sid</link>=Off
|
||
</para>
|
||
<para>
|
||
Использование прозрачного управления сессионным ID не рекомендуется.
|
||
Вы можете использовать его, если необходимо. Однако, отключение прозрачного
|
||
управления повышает безопасность сессий в целом, убирая возможность
|
||
инъекции сессионного ID и его кражи.
|
||
</para>
|
||
<note>
|
||
<para>
|
||
Идентификатор сессии может утечь через закладку в браузере, URL посланый по почте,
|
||
сохраненный исходник HTML.
|
||
</para>
|
||
</note>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.trans-sid-tags">session.trans_sid_tags</link>=[игнорируемые теги]
|
||
</para>
|
||
<para>
|
||
(PHP 7.1.0 >=) Вы не должны перезаписывать ненужные HTML-теги.
|
||
Значения по умолчанию должно быть достаточно для большинства случаев. Старые версии PHP
|
||
для этого используют <link linkend="ini.url-rewriter.tags">url_rewriter.tags</link>.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.trans-sid-hosts">session.trans_sid_hosts</link>=[список хостов]
|
||
</para>
|
||
<para>
|
||
(PHP 7.1.0 >=) Эта настройка определяет белый список хостов, для которых
|
||
разрешено прозрачное управление идентификаторами сессий. Никогда не добавляйте
|
||
недоверенные хосты. Если данная настройка пустая, то будет разрешено только для $_SERVER['HTTP_HOST'].
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.referer-check">session.referer_check</link>=[ваш исходный URL]
|
||
</para>
|
||
<para>
|
||
Если <link linkend="ini.session.use-trans-sid">session.use_trans_sid</link>
|
||
включен, то рекомендуется использовать эту опцию, если это возможно.
|
||
Это уменьшает риск для инъекции сессионного ID. Если ваш сайт
|
||
находится по адресу http://example.com/, то установите этой опции значение http://example.com/.
|
||
Обратите внимание, что при использовании HTTPS, браузер не отправляет
|
||
referrer заголовок. Таким образом, этот параметр не является достаточно
|
||
надежным показателем безопасности, но, все же, рекомендуется его использовать.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.cache-limiter">session.cache_limiter</link>=nocache
|
||
</para>
|
||
<para>
|
||
Убедитесь, что содержимое HTTP не кешируется для аутентификационной сессии.
|
||
Допускается кешировать только неконфиденциальный контент. Иначе
|
||
содержимым могут воспользоваться. Можно использовать значение "private",
|
||
если содержимое HTTP не содержит чувствительные к безопасности данные. Учтите, что
|
||
"private" может оставлять конфиденциальные данные в общем кеше клиентов.
|
||
Значение "public" можно использовать только, если HTTP-контент вообще не содержит
|
||
никаких конфиденциальных данных.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.sid-length">session.sid_length</link>="48"
|
||
</para>
|
||
<para>
|
||
(PHP 7.1.0 >=) Чем длинее идентификатор сессии, тем он надежнее.
|
||
Рекомендуемая длина - 32 символа и больше. В любом случае, не менее 26 символов
|
||
требуется для <link linkend="ini.session.sid-bits-per-character">session.sid_bits_per_character</link>="5".
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.sid-bits-per-character">session.sid_bits_per_character</link>="6"
|
||
</para>
|
||
<para>
|
||
(PHP 7.1.0 >=) Чем больше бит используется для символов идентификатора
|
||
сессии, тем более надежные идентификаторы будут созданы для той же длины идентификатора сессии.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.hash-function">session.hash_function</link>="sha256"
|
||
</para>
|
||
<para>
|
||
(PHP 7.1.0 <) Более сложная хеш-функция будет создавать более сложный сессионный ID.
|
||
Хотя коллизии с хешом почти не происходят и с MD5-хешом, тем не менее
|
||
разработчику лучше использовать функции SHA-2 или новее. Разработчики
|
||
также могут использовать сложные функции sha384 и sha512. Удостовертесь, что вы используете
|
||
достаточно <link linkend="ini.session.entropy-length">энтропии</link> для этих функций.
|
||
</para>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<para>
|
||
<link linkend="ini.session.save-path">session.save_path</link>=[общедоступный каталог для чтения]
|
||
</para>
|
||
<para>
|
||
Если установлено в общедоступный каталог для чтения всем, такой как
|
||
<filename>/tmp</filename> (по умолчанию), другие пользователи на
|
||
сервере могут захватить сеансы, получив список
|
||
файлов в этом каталоге.
|
||
</para>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
</sect1>
|
||
|
||
</chapter>
|
||
|
||
<!-- Keep this comment at the end of the file
|
||
Local variables:
|
||
mode: sgml
|
||
sgml-omittag:t
|
||
sgml-shorttag:t
|
||
sgml-minimize-attributes:nil
|
||
sgml-always-quote-attributes:t
|
||
sgml-indent-step:1
|
||
sgml-indent-data:t
|
||
indent-tabs-mode:nil
|
||
sgml-parent-document:nil
|
||
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
||
sgml-exposed-tags:nil
|
||
sgml-local-catalogs:nil
|
||
sgml-local-ecat-files:nil
|
||
End:
|
||
vim600: syn=xml fen fdm=syntax fdl=2 si
|
||
vim: et tw=78 syn=sgml
|
||
vi: ts=1 sw=1
|
||
-->
|
||
|