Harden UI: login brute-force throttle, security headers, Secure cookie flag

- New in-memory login throttle (handler/login_throttle.go): 5 failed
  attempts per IP or per username within 5 minutes locks that key out for
  5 minutes, applied to both /login and the TOTP verification step, which
  previously had no rate limiting at all
- router.New now adds middleware.Secure with X-Frame-Options,
  X-Content-Type-Options, Referrer-Policy, and HSTS (only when cookies
  are Secure, implying an HTTPS deployment). No CSP: the existing
  templates rely on inline <script> blocks, so a CSP strict enough to
  matter would need 'unsafe-inline' anyway
- All session/auth cookies now set Secure based on the new
  --cookie-secure flag / WGUI_COOKIE_SECURE env var (default true) so the
  session cookie is never sent over plain HTTP unless explicitly opted
  into an HTTP-only LAN deployment

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ATVUwTa4Pqwq26orW5BcDW
This commit is contained in:
sysops
2026-07-29 15:03:21 +02:00
co-authored by Claude Sonnet 5
parent 1539c589a1
commit 4d171b4ff7
7 changed files with 251 additions and 0 deletions
+3
View File
@@ -142,6 +142,7 @@ func doRefreshSession(c echo.Context) {
Path: cookiePath,
MaxAge: maxAge,
HttpOnly: true,
Secure: util.CookieSecure,
SameSite: http.SameSiteLaxMode,
}
sess.Save(c.Request(), c.Response())
@@ -152,6 +153,7 @@ func doRefreshSession(c echo.Context) {
cookie.Value = oldCookie.Value
cookie.MaxAge = maxAge
cookie.HttpOnly = true
cookie.Secure = util.CookieSecure
cookie.SameSite = http.SameSiteLaxMode
c.SetCookie(cookie)
}
@@ -273,6 +275,7 @@ func clearSession(c echo.Context) {
cookie.Path = cookiePath
cookie.MaxAge = -1
cookie.HttpOnly = true
cookie.Secure = util.CookieSecure
cookie.SameSite = http.SameSiteLaxMode
c.SetCookie(cookie)
}