logout (routers/auth.py:118) лишь просит браузер удалить cookie; серверного списка отозванных токенов или версии токена нет — decode_token проверяет только подпись/aud/exp. Украденный или оставшийся токен живёт до истечения TTL (игрок — 7 дней, админ — 8 ч) после выхода и после смены пароля (в т.ч. сброса «забытого» пароля админом — routers/users.py:121, routers/admin.py:115). Компрометацию аккаунта смена пароля не прекращает.
Evidence: старый токен, предъявленный вручную после logout → GET /api/users/me = 200; то же после смены пароля → 200.
Рекомендация:token_version у пользователя (claim в JWT, сверка в auth/deps.py), инкремент при смене пароля и «выйти со всех устройств»; либо denylist по jti / отсечение по iat < password_changed_at. Затрагивает models.py (миграция), core/security.py, auth/deps.py.
**Severity (предложение): High.**
`logout` (`routers/auth.py:118`) лишь просит браузер удалить cookie; серверного списка отозванных токенов или версии токена нет — `decode_token` проверяет только подпись/`aud`/`exp`. Украденный или оставшийся токен живёт до истечения TTL (игрок — **7 дней**, админ — 8 ч) **после выхода** и **после смены пароля** (в т.ч. сброса «забытого» пароля админом — `routers/users.py:121`, `routers/admin.py:115`). Компрометацию аккаунта смена пароля не прекращает.
**Evidence:** старый токен, предъявленный вручную после `logout` → `GET /api/users/me` = `200`; то же после смены пароля → `200`.
**Рекомендация:** `token_version` у пользователя (claim в JWT, сверка в `auth/deps.py`), инкремент при смене пароля и «выйти со всех устройств»; либо denylist по `jti` / отсечение по `iat < password_changed_at`. Затрагивает `models.py` (миграция), `core/security.py`, `auth/deps.py`.
Обнаружено при работе над #25 (находка F2).
Agent
added this to the 1.37 - смена аутентификации и смежный пен тест milestone 2026-09-13 16:17:30 +03:00
Отзыв JWT: claim ver + users.token_version (инкремент при смене/сбросе пароля — все прежние сессии мертвы), jti-denylist при logout (отзыв именно предъявленного токена). Своё устройство при смене пароля остаётся в сессии. Миграция 0013. Мёрж и закрытие — за вами.
F2 реализовано в PR #63 — https://gitea.arseniev.info/NotBigGhost/ForbiddenStarsApp/pulls/63
Отзыв JWT: claim `ver` + `users.token_version` (инкремент при смене/сбросе пароля — все прежние сессии мертвы), jti-denylist при logout (отзыв именно предъявленного токена). Своё устройство при смене пароля остаётся в сессии. Миграция `0013`. Мёрж и закрытие — за вами.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity (предложение): High.
logout(routers/auth.py:118) лишь просит браузер удалить cookie; серверного списка отозванных токенов или версии токена нет —decode_tokenпроверяет только подпись/aud/exp. Украденный или оставшийся токен живёт до истечения TTL (игрок — 7 дней, админ — 8 ч) после выхода и после смены пароля (в т.ч. сброса «забытого» пароля админом —routers/users.py:121,routers/admin.py:115). Компрометацию аккаунта смена пароля не прекращает.Evidence: старый токен, предъявленный вручную после
logout→GET /api/users/me=200; то же после смены пароля →200.Рекомендация:
token_versionу пользователя (claim в JWT, сверка вauth/deps.py), инкремент при смене пароля и «выйти со всех устройств»; либо denylist поjti/ отсечение поiat < password_changed_at. Затрагиваетmodels.py(миграция),core/security.py,auth/deps.py.Обнаружено при работе над #25 (находка F2).
F2 реализовано в PR #63 — #63
Отзыв JWT: claim
ver+users.token_version(инкремент при смене/сбросе пароля — все прежние сессии мертвы), jti-denylist при logout (отзыв именно предъявленного токена). Своё устройство при смене пароля остаётся в сессии. Миграция0013. Мёрж и закрытие — за вами.