Severity: Medium | Area: frontend/auth | Evidence: app/auth/oauth/callback/page.tsx:38-40 — returnPath = sessionStorage.getItem('oauth_return_path') || '/' then router.replace(returnPath)
Impact: Any code that can write sessionStorage controls post-login navigation (internal redirect abuse). Fix: Validate the path starts with / and is not ///protocol-relative. Acceptance: External/evil return paths are rejected.
Severity: Medium | Area: frontend/auth | Evidence:
app/auth/oauth/callback/page.tsx:38-40—returnPath = sessionStorage.getItem('oauth_return_path') || '/'thenrouter.replace(returnPath)Impact: Any code that can write sessionStorage controls post-login navigation (internal redirect abuse). Fix: Validate the path starts with
/and is not///protocol-relative. Acceptance: External/evil return paths are rejected.