Глоссарий

Что такое фиксация сессии — заставить жертву войти с ID, который атакующий уже знает

Фиксация сессии заставляет жертву войти с ID сессии, который знает атакующий. Как это работает и защита: новый ID сессии при входе, без ID в URL, флаги cookie.

Опубликовано 2026-06-11 Обновлено 2026-10-06 6 мин чтения
На этой странице

Фиксация сессии — это когда жертва входит с ID, который подготовил атакующий. Вот как она работает и как её надёжно предотвратить (без шагов атаки).

Почему это работает

Причина — в конструкции, где ID сессии не меняется при входе. Если он не меняется, ID, который атакующий знал до входа, всё ещё работает как «аутентифицированный» после входа.

1) Атакующий заставляет жертву использовать известный ID сессии (через ссылку и т. п.)
↓ жертва входит с этим ID, всё ещё установленным
2) ID не регенерируется = тот же ID становится «аутентифицированным»
↓ атакующий знал этот ID всё это время
3) Доступ с тем же ID = выдача себя за жертву
Если ID не меняется при входе, ID, известный атакующему заранее, становится аутентифицированным как есть.

Это может сочетаться с CSRF или XSS, но суть самой фиксации — одна вещь: ID не был регенерирован при входе.

Руководство японского IPA (Агентства по развитию информационных технологий) «How to Secure Your Website» относит это к одной из форм ненадлежащего управления сессиями и говорит, что следить за этим нужно на любом сайте с функцией входа. Коренное исправление по нему — начинать новую сессию после успешного входа.

Фиксация, перехват и CSRF

Эти три легко перепутать. Все они злоупотребляют состоянием «пользователь вошёл», но различаются тем, что есть у атакующего, и тем, какая защита работает.

ПунктФиксация сессииПерехват сессииCSRF
Что есть у атакующегоID, который он подготовил (известен с самого начала)Украденный, уже выданный IDНикакого ID
Что происходит с жертвойОна входит с подброшенным IDУ неё крадут выданный IDЕё заставляют отправить непреднамеренный запрос
Основная защитаРегенерация ID при входеHttpOnly/Secure, защита от XSS, короткий срок жизниCSRF-токены, SameSite

Фиксацию устраняет в корне один шаг — регенерация ID при входе.

Защита: регенерируйте ID при входе

1

Регенерируйте ID сессии при успешном входе (самое важное)

В тот миг, когда аутентификация успешна, отбросьте старый ID и выдайте новый ID сессии (session regenerate/renew у большинства фреймворков). Любой заранее подброшенный ID немедленно становится недействительным. Регенерируйте и при эскалации привилегий (например, при получении прав администратора).
2

Не принимайте ID сессии через URL

Обрабатывайте ID сессии в cookie и игнорируйте ID, заданный в параметре URL. Закройте путь, которым атакующий заставляет жертву принять «зафиксированный» ID.
3

Выставьте флаги cookie

Выставьте сессионным cookie HttpOnly (JS не может читать), Secure (только HTTPS) и SameSite (ограничивает межсайтовую отправку). Это вместе ослабляет связанные пути перехвата.
4

Разумно завершайте сессии

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

Руководство OWASP по управлению сессиями рекомендует регенерировать ID при каждой смене привилегий и использовать «строгий» механизм, который принимает только ID, сгенерированные самим сервером. «Нестрогий» механизм, принимающий неизвестный ID, принесённый извне, оставляет возможность принять ID, выбранный атакующим.

Что делают популярные фреймворки по умолчанию

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

СредаПоведение по умолчаниюЧто проверить, если пишете сами
PHP (обычные сессии)Сам не регенерирует; session.use_strict_mode по умолчанию 0Вызывайте session_regenerate_id(true) при успешном входе; установите use_strict_mode в 1
LaravelРегенерирует автоматически при аутентификации, если используете стартовый набор или FortifyЕсли пишете вход вручную, вызывайте $request->session()->regenerate()
Spring SecurityВключено по умолчанию (changeSessionId на Servlet 3.1+)Убедитесь, что никто не выставил sessionFixation().none()

В PHP настройки, передающие ID сессии в URL (включение session.use_trans_sid, отключение session.use_only_cookies), объявлены устаревшими в PHP 8.4. Если вы переносите старый конфигурационный файл, пересмотрите их.

Как проверить свой сайт

На сайте, которым вы управляете, проверьте эти четыре вещи. Хватит инструментов разработчика.

  1. В инструментах разработчика на вкладке «Application» (в Firefox — «Хранилище») запишите значение сессионного cookie, затем посмотрите снова после входа. Если оно не изменилось, ID не регенерируется при входе
  2. Проверьте, что URL страницы входа и страниц после входа не содержат ID сессии вроде PHPSESSID= или ;jsessionid=
  3. На той же панели проверьте, что у сессионного cookie есть HttpOnly, Secure и SameSite
  4. После выхода верните старое значение cookie и перезагрузите страницу; убедитесь, что вы снова не вошли

Атрибуты cookie проверяет и аудит безопасности сайта — для сайтов, владение которыми вы подтвердили. Если внести проверку 1 в автоматический тест на любые изменения потока входа, вы сразу заметите, если регенерация пропадёт.

Мнение этого сайта: не отключайте «регенерацию» во фреймворке

Фиксация сессии в основном предотвращается одним шагом: регенерацией ID при входе, а не сложным самописным кодом. Ключ в том, чтобы случайно не отключить и не забыть вызвать механизм, который ваш фреймворк уже предоставляет. Использовать безопасные значения по умолчанию проверенной реализации лучше, чем самому собирать управление сессиями. На этом сайте мы держимся правила «не пишите аутентификацию/работу с ключами сами; не отключайте безопасные значения по умолчанию». Как и с IDOR, аутентификация/авторизация должны обеспечиваться механизмом на каждом запросе.

Источники (первичные)

  • IPA, «How to Secure Your Website», 1.4 Ненадлежащее управление сессиями — ipa.go.jp (начинать новую сессию после входа; не помещать ID в URL; на японском)
  • OWASP Session Management Cheat Sheet — cheatsheetseries.owasp.org (регенерация при смене привилегий, строгий механизм, атрибуты cookie)
  • MITRE CWE-384: Session Fixation — cwe.mitre.org
  • Руководство PHP, «Runtime Configuration» (сессии) — php.net (значения по умолчанию, например use_strict_mode; устаревание в 8.4)
  • Документация Laravel, «HTTP Session» — laravel.com / Spring Security, «Authentication Persistence and Session Management» — docs.spring.io

Читать дальше

Классификация

CWE классифицирует типы слабостей, из-за которых возникают уязвимости; MITRE ATT&CK классифицирует техники атакующих. Обе системы ведёт MITRE, и они широко используются для разметки уязвимостей и правил обнаружения.

CWE (тип слабости)

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

QЧем фиксация отличается от перехвата сессии?
A

Перехват крадёт уже выданный кому-то ID сессии. Фиксация — наоборот: атакующий заставляет жертву использовать ID, который он уже знает, а затем ждёт, пока жертва войдёт с ним. Он не крадёт; он добивается аутентификации известного атакующему ID.

QКакая защита главная?
A

Регенерировать ID сессии в момент входа. У большинства фреймворков/библиотек сессий это есть (session regenerate/renew): при успешной аутентификации отбросить старый ID и выдать новый. Уже это делает недействительным любой ID, подброшенный атакующим заранее. Регенерируйте и при смене привилегий (например, при получении прав администратора).

QПочему опасно помещать ID сессии в URL?
A

ID в URL легко утекает через общие ссылки, заголовок Referer, логи и историю браузера, а это даёт атакующему способ заставить жертву использовать «зафиксированный» ID. Обрабатывайте ID сессии в cookie, а не в параметрах URL, и не принимайте ID, заданный через URL.

QКак проверить, уязвим ли мой сайт к фиксации сессии?
A

На своём сайте откройте инструменты разработчика браузера и сравните значение сессионного cookie до и после входа. Если после входа значение то же, ID не регенерируется, и это нужно исправить. Также проверьте, что ID сессии не появляется в URL и что у cookie выставлены HttpOnly, Secure и SameSite.

QКакие настройки PHP предотвращают фиксацию сессии?
A

При успешном входе вызывайте session_regenerate_id(true), чтобы перейти на новый ID. В php.ini установите session.use_strict_mode в 1, чтобы сервер отклонял ID, которые он не выдавал (по умолчанию 0). Оставьте session.use_only_cookies на значении по умолчанию 1, а session.use_trans_sid — на значении по умолчанию 0, чтобы ID никогда не передавались в URL.

QЕсли я использую JWT, возможна ли фиксация сессии?
A

Если вы не используете серверный ID сессии и при успешном входе выдаёте новый токен, атаку «добиться аутентификации заранее выбранного ID» провести трудно. Но если токен, выданный до входа, продолжает использоваться и после входа, может возникнуть та же проблема. Каким бы ни был механизм, правило одно: в момент входа выдавать новый идентификатор.