aboutsummaryrefslogtreecommitdiffstats
path: root/web/web.go
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-16 14:02:48 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-16 14:02:48 -0800
commit2e459c911031669080bc110059cf2b4b19c5379d (patch)
tree60650c8fc5e2d919b5e6fdb4b073b0f0f4d54d8e /web/web.go
parent52ea335714f2b495b92f87636c269b73b4067066 (diff)
downloadneko-2e459c911031669080bc110059cf2b4b19c5379d.tar.gz
neko-2e459c911031669080bc110059cf2b4b19c5379d.tar.bz2
neko-2e459c911031669080bc110059cf2b4b19c5379d.zip
Enhance CSRF protection for login page
Login form now includes a CSRF token from the cookie as a hidden form field. The CSRF middleware accepts tokens from either the X-CSRF-Token header (for JS clients) or the csrf_token form field (for HTML forms). Removed /login from the CSRF exclusion list so login POSTs are now validated. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'web/web.go')
-rw-r--r--web/web.go10
1 files changed, 7 insertions, 3 deletions
diff --git a/web/web.go b/web/web.go
index 997a05a..bb11d60 100644
--- a/web/web.go
+++ b/web/web.go
@@ -380,11 +380,15 @@ func CSRFMiddleware(cfg *config.Settings, next http.Handler) http.Handler {
}
path := strings.TrimSuffix(r.URL.Path, "/")
- isExcluded := path == "/api/login" || path == "/login" || path == "/api/logout"
+ isExcluded := path == "/api/login" || path == "/api/logout"
if (r.Method == http.MethodPost || r.Method == http.MethodPut || r.Method == http.MethodDelete) && !isExcluded {
- headerToken := r.Header.Get("X-CSRF-Token")
- if headerToken == "" || headerToken != token {
+ // Accept token from header (JS clients) or form field (HTML forms)
+ submittedToken := r.Header.Get("X-CSRF-Token")
+ if submittedToken == "" {
+ submittedToken = r.FormValue("csrf_token")
+ }
+ if submittedToken == "" || submittedToken != token {
http.Error(w, "CSRF token mismatch", http.StatusForbidden)
return
}