Отчёт об исправлении: ротация invite-кодов команд
Дата исправления: 6 августа 2026 года
Статус: исправлено и развёрнуто в production
Источник: отчёт участника Open Beta (0ffs3c, APT SANDWORM) от 5 августа 2026 года
Описание
Подтверждена логическая уязвимость в persistent-командах: после выпуска нового invite-кода ранее созданные коды оставались действительными до своего срока истечения. В результате человек, сохранивший старый код, мог вступить в команду после того, как капитан уже выпустил замену.
Значение invite-кода не даёт доступ к аккаунтам, флагам или чужим инстансам, однако создаёт несанкционированный путь вступления в команду и нарушает ожидания капитана о ротации приглашения.
Причина
Модель данных поддерживала revoked_at, а проверка вступления уже отклоняла отозванный код. Но при создании нового invite-кода предыдущие строки platform_team_join_codes не помечались отозванными.
Исправление
- Введена политика одного активного invite-кода на persistent-команду.
- При выпуске нового кода все предыдущие активные коды этой команды получают
revoked_at. - Отзыв старых кодов и выпуск нового происходят в одной PostgreSQL-транзакции.
- Добавлена advisory lock на команду: параллельные запросы не могут оставить несколько одновременно действительных кодов.
- В migration
0031_rotate_platform_join_codes.sqlвсе ранее накопленные активные коды отозваны, кроме самого свежего для каждой команды. - Поведение in-memory реализации приведено к production-семантике для тестов и standalone-режима.
Проверка
Добавлен регрессионный тест сценария из отчёта:
- Капитан выпускает invite-код A.
- Капитан выпускает invite-код B.
- Вступление с A возвращает
404 not_found. - Вступление с B продолжается в штатном режиме.
Проверки пакетов internal/app, internal/store и internal/httpapi прошли успешно.
Развёртывание
Исправление развёрнуто rolling-обновлением на обе реплики API:
Версия production API: sqwd/platform-api:0.1.0-20260806.2. После обновления health-check обеих реплик прошёл успешно.
Рекомендации пользователям
Капитанам не требуется выполнять дополнительные действия. После исправления действительным считается только последний выданный invite-код команды. Если ранее созданный код мог быть раскрыт, достаточно выпустить новый: все старые коды будут автоматически отозваны.
Благодарность
Спасибо автору отчёта за аккуратное воспроизведение, отсутствие воздействия на чужие данные и подробные шаги проверки. Это помогло быстро подтвердить и устранить проблему.