package middleware import ( "net/http" "github.com/gorilla/sessions" ) // SecurityHeaders adds security and cache-control headers to all responses func SecureHeaders(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Set strict cache control headers w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0") w.Header().Set("Pragma", "no-cache") w.Header().Set("Expires", "0") // Add security headers with updated CSP w.Header().Set("Content-Security-Policy", "default-src 'self'; "+ "script-src 'self' https://unpkg.com/htmx.org@* 'unsafe-inline'; "+ "style-src 'self' 'unsafe-inline'; "+ "img-src 'self' data:; "+ "connect-src 'self'; "+ "frame-ancestors 'none'; "+ "form-action 'self'") w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("X-Frame-Options", "DENY") w.Header().Set("X-XSS-Protection", "1; mode=block") next.ServeHTTP(w, r) }) } // middleware/csrf.go func CSRFMiddleware(store sessions.Store) Middleware { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method == "POST" { session, _ := store.Get(r, "auth-session") csrfToken := session.Values["csrf_token"].(string) formToken := r.FormValue("_csrf") if csrfToken != formToken { http.Error(w, "Invalid CSRF token", http.StatusForbidden) return } } next.ServeHTTP(w, r) }) } }