From eb089ef4c9416bd3d5642bb5a4437355ffa2fdd0 Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Wed, 3 Jun 2026 00:35:02 +0000 Subject: fix: add CSRF and WebSocket origin protection to Claudomator proxy Token-based CSRF is impractical for a reverse proxy whose UI doesn't know Doot's session tokens, so state-changing requests to /claudomator/* are now validated against the configured WebAuthn origin via Origin/Referer header. WebSocket upgrades reject mismatched or missing Origin headers before hijacking the connection. Both checks are no-ops when WebAuthnOrigin is unset (local dev). Co-Authored-By: Claude Sonnet 4.6 --- cmd/dashboard/main.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'cmd/dashboard') diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go index 09292b4..c648ede 100644 --- a/cmd/dashboard/main.go +++ b/cmd/dashboard/main.go @@ -164,7 +164,7 @@ func main() { r.Use(sessionManager.LoadAndSave) // Session middleware must be applied globally // Initialize Claudomator reverse proxy - claudomatorProxy := handlers.NewClaudomatorProxy(cfg.ClaudomatorURL) + claudomatorProxy := handlers.NewClaudomatorProxy(cfg.ClaudomatorURL, cfg.WebAuthnOrigin) // Rate limiter for auth endpoints authRateLimiter := appmiddleware.NewRateLimiter(config.AuthRateLimitRequests, config.AuthRateLimitWindow) @@ -234,9 +234,10 @@ func main() { // GitHub webhook: no auth (GitHub POSTs with HMAC, no session) r.Post("/claudomator/api/webhooks/github", claudomatorProxy.ServeHTTP) - // All other Claudomator routes: RequireAuth only, no CSRF + // All other Claudomator routes: RequireAuth + origin check (CSRF protection for proxy) r.Group(func(r chi.Router) { r.Use(authHandlers.Middleware().RequireAuth) + r.Use(auth.OriginCheck(cfg.WebAuthnOrigin)) r.Handle("/claudomator/*", claudomatorProxy) }) -- cgit v1.2.3