# 2026-03-27 Auth Session Hardening Remediation ## Scope - Q-001 session hardening - Q-002 OAuth return_to trust-boundary hardening - Q-003 security-sensitive random fail-close hardening - real-browser E2E closure after the auth/session model change ## Implemented Remediation - Backend refresh continuity now uses a backend-managed `HttpOnly` refresh cookie. - Frontend access token, current user, and current roles are memory-only; they are no longer persisted into `localStorage` or `sessionStorage`. - Backend now also sets a non-sensitive session-presence cookie (`ums_session_present`) so the frontend can distinguish: - "there may be a server session worth restoring" - "there is clearly no session, so do not probe `/auth/refresh`" - Frontend `AuthProvider` now: - skips restore probing when the session-presence cookie is absent - keeps restore probing available when the cookie exists, including page reload on protected pages - stops performing its own redirect on restore failure and lets `RequireAuth` preserve the original `from` route - exports effective auth state from the in-memory session store to avoid post-login route races - OAuth `return_to` no longer trusts request-derived forwarded origin inference and is restricted to: - absolute frontend paths - explicitly allowlisted origins - `crypto/rand` failure no longer silently degrades into weaker random generation for JWT JTI, email code, or captcha identifiers. ## Validation Validated on 2026-03-27 with: ```powershell go test ./... -count=1 go vet ./... go build ./cmd/server cd D:\project\frontend\admin npm.cmd run test:run npm.cmd run lint npm.cmd run build powershell -ExecutionPolicy Bypass -File .\scripts\run-playwright-auth-e2e.ps1 ``` ## Latest Real Result - Backend gates: passed - Frontend gates: passed - Real browser CDP E2E: passed - Verified E2E scenarios: - `admin-bootstrap` - `public-registration` - `email-activation` - `login-surface` - `auth-workflow` - `responsive-login` - `desktop-mobile-navigation` ## Real Outcome - Q-001 is no longer a current open high-risk issue in the project's implemented session model. - Q-002 is no longer a current open high-risk issue in the OAuth frontend return path trust boundary. - Q-003 is no longer a current open medium-risk issue in security-sensitive randomness handling. - This remediation also closed a real regression introduced during the session hardening pass: - public or unauthenticated route loads no longer emit browser console `400 Bad Request` noise from blind `/auth/refresh` probing - protected-route redirects again preserve the original route intent through `RequireAuth` ## Remaining Real Gaps - Q-004 automation coverage depth is still insufficient in several low-level/backend modules and key frontend containers. - Q-005 dev toolchain SCA findings are still not fully cleared. - Q-006 external alert delivery evidence is still not fully closed.