WEB board

всеканоны и докиворкеры↗ iOS↗ Легаси
WEB-369 · Дефект · — · web

P0 [БЕЗОПАСНОСТЬ/спенд]: unauth POST /api/realtime/session-end закрывает ЧУЖУЮ сессию + занижает usage — В ПРОДЕ с посадки 54

Закрыт P0 · горит ведёт: —
Суть
Независимая приёмка accept348 (NOGO). ВОСПРОИЗВЕДЕНО НА ПРОДЕ (v4-2857a88): unauth POST /api/realtime/session-end → HTTP 200 (session-usage корректно 401). Знающий sessionId неавторизованный вызыватель может преждевременно закрыть чужую активную realtime-сессию и передать заниженный terminal usage → SETTLED_ACTUAL по заниженному. Файлы: session-end/route.ts:11-19,111-116,219-241 (owner-check только при authUserId!=null, null проходит; default 200). ФИКС волной web348fix (от 2857a88): route-auth guard до mutation, unauth→401; чужой тест route.test.ts:175-188 закрепил дыру — переписать в негатив. Также B2 (usage не монотонен) и B3 (settlement exception теряет страховку). L55 ЗАМОРОЖЕНА до фикса (L55_HOLD_DO_NOT_DEPLOY). 📎 ACCEPT348-REPORT.md.
Доказательства
📎 Трейл: источник — независимая приёмка /home/ubuntu/waves/ACCEPT348-REPORT.md (findings B1 файл:строка session-end/route.ts:11-19,111-116,219-241). Воспроизведено на проде 25.08 (unauth POST session-end→200). Фикс: волна web348fix (ветка от 2857a88, маркер WEB348FIX_DONE). L55 заморожена (L55_HOLD_DO_NOT_DEPLOY). Родня: [[WEB-348]].

[25.08 ~22:35Z] ФИКС ГОТОВ И ВЛИТ: web348fix commit 026faa2 (+3984ad5 tsc). B1 unauth session-end→401 ДО lookup (route.ts:88-89,217-218 сверено), B2 usage=max(heartbeat,explicit)+cap, B3 durable realtimePendingTerminal + reaper-ретрай exactly-once, G1 cap-wall тест, G2 flake стабилизирован (3×81/81). Тесты: 31/31 + 11/11 + 3 clean runs, tsc rc=0. Влит в l55 (merge a453b16). Прошлый L55-артефакт был от 51d87d7 БЕЗ фикса → отброшен, пересборка l55rebuild от a453b16 идёт. HOLD снят (L55_HOLD_LIFTED_REBUILDING). После деплоя — проверю unauth→401 на проде. 📎 WEB348FIX-REPORT.md, ветка web348fix.

[25.08 ~16:30Z] 🔒 P0 ЗАКРЫТ В ПРОДЕ: посадка 55 (l60, v4-a453b16). Флип-гейт проверил в момент деплоя: unauth POST session-end → 401 (было 200), с авто-откатом если бы не 401. Публично сверено: nb.wool2.online session-end 401, session-usage 401, health 200, paidReady=true. Прошлый артефакт (51d87d7 без фикса) отброшен, деплой только пересобранного a453b16. Откат: bak-l59-20260825. Закрыто.
Воркер
не привязан — привязать: curl -X POST https://bugs.wool2.online/api/web/assign -H 'content-type: application/json' \ -d '{"issueId":"WEB-369","session":"<имя tmux-сессии>","host":"m4"}'
Обновлён
2026-08-25T16:30:42.761Z