Skip to content

fix(auth): ротация API-токена против token fixation - #435

Closed
Ibochkarev wants to merge 1 commit into
betafrom
fix/issue-412-token-fixation-rotation
Closed

fix(auth): ротация API-токена против token fixation#435
Ibochkarev wants to merge 1 commit into
betafrom
fix/issue-412-token-fixation-rotation

Conversation

@Ibochkarev

Copy link
Copy Markdown
Member

Описание

На login / register (auto-login) / email verify / checkout auto-login больше не делается rebind guest API-токена к аккаунту. Выдаётся новый токен, guest draft мигрирует при безопасном владельце, старый guest/own токен отзывается, вызывается session_regenerate_id(true).

Закрывает классический token fixation: planted ms3_token=T после входа жертвы больше не даёт доступ по тому же T.

Тип изменений

  • Исправление бага (non-breaking change)
  • Новая функциональность (non-breaking change)
  • Breaking change (изменение, ломающее обратную совместимость)
  • Рефакторинг (без изменения функциональности)
  • Документация
  • Другое (опишите):

Связанные Issues

Closes #412

Смежно с #369 (checkout email capture) — здесь ещё и Customer::autoLoginCustomer переведён на тот же establishApiSession.

Как это было протестировано?

cd core/components/minishop3
php -l src/Services/Customer/AuthManager.php
php tests/ApiTokenRotationPolicyTest.php   # exit 0
composer ci:php                           # exit 0

Gate E (эта сессия):

  • php -l touched PHP — OK

  • php tests/ApiTokenRotationPolicyTest.php — OK (policy + regression guards)

  • composer ci:php — OK (exit 0)

  • Vue — n/a

  • Ручное тестирование

  • Автоматические тесты (composer ci:php)

  • Тестирование на разных версиях PHP/MODX

Конфигурация тестирования:

  • MiniShop3: ветка fix/issue-412-token-fixation-rotation
  • MODX: n/a (smoke без MODX)
  • PHP: 8.2+

Скриншоты (если применимо)

n/a

Чеклист

  • Код соответствует стилю проекта
  • Добавлены/обновлены комментарии в сложных местах
  • Изменения не ломают существующую функциональность
  • Лексиконы добавлены на двух языках (ru/en) — не требуются
  • PHPStan проходит без новых ошибок (локально; в CI пока нет)
  • ESLint — n/a
  • CHANGELOG.md — на релизе

Дополнительные заметки

Поведение для клиентов: после login/register/verify в ответе/cookie приходит новый token (значение меняется). Guest-корзина сохраняется через migrate draft.

Отложено (не блокер): Register при редком fail createToken после уже созданного customer отдаёт failure (повтор → email занят). Follow-up UX.

Review: code-reviewer, thermo-nuclear, security-review, silent-failure-hunter; 1 fix-loop (checkout autoLogin + migrate hardening + HTML verify).

@Ibochkarev Ibochkarev added priority: high Важно исправить в ближайшее время bug Something isn't working labels Jul 23, 2026
@Ibochkarev
Ibochkarev requested a review from biz87 July 23, 2026 15:51
@Ibochkarev
Ibochkarev force-pushed the fix/issue-412-token-fixation-rotation branch 4 times, most recently from ee85d13 to 658244e Compare July 28, 2026 04:50
@Ibochkarev
Ibochkarev force-pushed the fix/issue-412-token-fixation-rotation branch 2 times, most recently from 81a9cce to b2ea3b8 Compare July 29, 2026 11:32
Rebinding a planted guest cookie to the victim account let an attacker
keep the same token after login. Always issue a new API token, migrate
the guest draft when safe, revoke the old guest/own token, and regenerate
the session id.
@Ibochkarev
Ibochkarev force-pushed the fix/issue-412-token-fixation-rotation branch from b2ea3b8 to bbf1eb6 Compare August 1, 2026 09:34
@biz87

biz87 commented Aug 1, 2026

Copy link
Copy Markdown
Member

Закрываю как субсумированный #321 (влит в beta, 6e15bf6).

AuthManager::establishApiSession() из этого PR делает ровно то же, что теперь делает AuthManager::establishCustomerSession() в beta:

  • всегда mint нового API-токена на login/register/verify (guest-токен не апгрейдится → token fixation закрыт);
  • перенос гостевой корзины на новый токен при безопасном владельце — предикат canTransferCartFromToken(prevOwnerId, customerId) в fix(customer): restore storefront login and session auth #321 эквивалентен здешнему canMigratePreviousApiToken (guest/own → перенос+revoke; foreign → не трогаем);
  • отзыв старого токена;
  • session_regenerate_id(true).

Регресс-покрытие ротации уже в beta (session-семантика — CustomerAuthSessionSemanticsTest; anti-fixation — через establishCustomerSession). Отдельная реализация establishApiSession больше не нужна.

Если в #321-версии найдётся пробел относительно этого PR — переоткроем точечно. Спасибо!

@biz87 biz87 closed this Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working priority: high Важно исправить в ближайшее время

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Login/Register: rebind guest API-токена без ротации (token fixation)

2 participants