ソースを参照

docs: mark SEC_REVIEW F36 as fixed in 2c3b65b

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
chiappa 4 日 前
コミット
a469e38cb3
1 ファイル変更35 行追加1 行削除
  1. 35 1
      doc/SEC_REVIEW.md

+ 35 - 1
doc/SEC_REVIEW.md

@@ -11,7 +11,7 @@
 >
 > Each finding is referenced as **F<N>** for later citation.
 >
-> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (3 fixed, 39 open).
+> **Findings rolled up:** 5 sev-3 (5 fixed, 0 open), 27 sev-2 (27 fixed, 0 open), 42 sev-1 (4 fixed, 38 open).
 
 ---
 
@@ -1244,6 +1244,40 @@
   (8h idle / 24h absolute). No "revoke session by user_id"
   primitive.
 - **Severity: 1**
+- **Status:** Fixed. `AuthRequiredMiddleware` now periodically
+  revalidates the cached `UserContext` against `GET /api/v1/admin/me`.
+  Cadence is configurable via `UI_SESSION_REVALIDATE_SECONDS` (default
+  300 seconds — 5 minutes); the middleware tracks the last revalidation
+  timestamp in a new `_revalidated_at` session slot owned by
+  `SessionManager`. Branches:
+  - **403 from the api** (`user_disabled` or `unknown impersonated user`)
+    → session cleared, error flash "Your access was revoked. Please
+    sign in again.", 302 to `/login`. The api's existing F11 disabled-
+    user path drives this from the server side, so `Disabled` /
+    deleted users are kicked off all live sessions within one
+    revalidation window.
+  - **404** → defensive same-as-403 (the api currently always returns
+    403 for missing/disabled users; treat 404 the same way for safety).
+  - **200 with changed role / display\_name / email** →
+    `SessionManager::updateUser()` rewrites the cached row but
+    preserves `_authenticated_at` / `_last_active` so the 8h idle and
+    24h absolute timeouts keep running off the original login.
+  - **200 unchanged** → just bump `_revalidated_at`.
+  - **api unreachable / 401 / 5xx / generic** → log a warning, mark
+    revalidated to avoid grinding on every request, and proceed with
+    the existing session. An api outage must not lock every live
+    session out, and the api itself is the authoritative gate on
+    every data call (it re-resolves the principal via
+    `X-Acting-User-Id` per request, F11), so a stale UI cache during
+    an outage cannot escalate privilege.
+  Pre-F36 ("legacy") sessions without `_revalidated_at` are
+  bootstrapped on first sight without an api call, so existing
+  rolling sessions don't all stampede the api on deploy. Tests:
+  `ui/tests/Integration/Auth/SessionRevalidationTest.php` covers
+  within-interval (no api call), past-interval-no-change,
+  past-interval-role-changed (admin → viewer is reflected
+  immediately), `user_disabled` and unknown-user kick paths,
+  api-unreachable-keeps-session, and the legacy-session bootstrap.
 
 ### F37 — Local-admin password hash algorithm not validated at boot
 - **File:** `ui/src/Auth/LocalLoginController.php:42, 78`