0.135.0

Security

  • PKCE для WebUI (C-SC-9): WebUI переведён с устаревшего grant_type=password (RFC 6749 §1.3.3, deprecated OAuth 2.0 Security BCP §2.4) на Authorization Code Flow с PKCE (RFC 7636). web/src/lib/api/client.ts:loginRequest реализует 3-шаговый нередиректный SPA-флоу через session cookie: POST /oauth/loginPOST /oauth/authorizecode_challenge S256 + CSRF double-submit) → POST /oauth/tokencode_verifier, сервер проверяет PKCE через verifyPKCE). Access-токен хранится в памяти, refresh-токен в httpOnly cookie tc_refresh.
  • Валидация redirect_uri (code-exfiltration protection): expectedWebUIRedirectURI в auth.go проверяет, что redirect_uri совпадает с Origin клиента (RFC 6454 canonicalization, host-match с r.Host). Fail-closed: запросы без валидного Origin для client_id="webui" отклоняются (браузеры шлют Origin на same-origin POST; API-скрипты используют password/refresh grant без redirect_uri). Проверка выполняется ДО session-lookup (DoS-amplification prevention).
  • Deprecation/Sunset headers: grant_type=password остаётся для API-клиентов (curl, скрипты), но ответы помечаются Deprecation: true + Sunset (RFC 8594) — удаление запланировано в v1.0.
  • Cleanup при partial-flow failure: если шаги authorize/token падают после успешного login (включая network errors, malformed JSON), клиент инвалидирует server-side session (POST /oauth/logout) + чистит cookies tc_session/tc_csrf на клиенте, предотвращая «полу-аутентифицированное» состояние.

Changed

  • authLimiter 5→15 req/min/IP: 3-шаговый PKCE-флоу = 3 запроса на попытку входа, поэтому общий лимит /oauth/* поднят с 5 до 15 (~5 попыток/мин для легитимного пользователя). Account-level lockout (5 неудач → 15 мин блок) остаётся основным заслоном от перебора.
  • /oauth/logout вынесен из-под authLimiter: logout вызывается как cleanup при ошибках login-флоу; rate-limiting оставил бы stale tc_session/tc_csrf. Logout идемпотентен (только очищает server-side state).
  • Doc-комментарий C-SC-9 в internal/auth/oauth.go обновлён: TODO(C-SC-9) выполнен, описана нередиректная SPA-архитектура.

Added

  • PKCE-хелперы generateCodeVerifier/generateCodeChallenge (S256) в client.ts, экспортированы для юнит-тестов.
  • Singleton-de-duplication для loginRequest (double-click protection — повторный вызов возвращает тот же промис).
  • Тесты: web/src/lib/api/pkce.test.ts (RFC 7636 test vector: verifier 43 chars, S256 challenge), интеграционные auth_test.go: TestPKCEFlow_LoginAuthorizeToken, TestPKCEFlow_RejectsWrongVerifier, TestPasswordGrant_DeprecationHeader, TestAuthorizationCodeGrant_NoDeprecationHeader, TestAuthorize_RejectsRedirectURIMismatch, TestAuthorize_AcceptsMatchingRedirectURI. Обновлён TestOAuthToken_RateLimited (лимит 15).