summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-26 07:01:25 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-26 07:01:25 -1000
commit8c2c88f90039e87b29ce32cd31b7b0361b5803d0 (patch)
tree6099e498084b876d343b071bbdf2cb62838eae7d /cmd
parentf5b997bfc4c77ef262726d14b30d387eb7acd1c6 (diff)
Phase 1: Critical security fixes
- Remove default password fallback - require DEFAULT_PASS in all environments - Fix XSS vulnerabilities in HTML generation (handlers.go:795,920) - Add security headers middleware (X-Frame-Options, CSP, HSTS, etc.) - Add rate limiting on login endpoint (5 req/15min per IP) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'cmd')
-rw-r--r--cmd/dashboard/main.go17
1 files changed, 9 insertions, 8 deletions
diff --git a/cmd/dashboard/main.go b/cmd/dashboard/main.go
index 40a5002..d7da061 100644
--- a/cmd/dashboard/main.go
+++ b/cmd/dashboard/main.go
@@ -21,6 +21,7 @@ import (
"task-dashboard/internal/auth"
"task-dashboard/internal/config"
"task-dashboard/internal/handlers"
+ appmiddleware "task-dashboard/internal/middleware"
"task-dashboard/internal/store"
)
@@ -59,11 +60,7 @@ func main() {
defaultUser = "admin"
}
if defaultPass == "" {
- if !cfg.Debug {
- log.Fatal("CRITICAL: DEFAULT_PASS must be set in production. Set DEBUG=true for development.")
- }
- log.Println("WARNING: Using default password - set DEFAULT_PASS for production")
- defaultPass = "changeme"
+ log.Fatal("CRITICAL: DEFAULT_PASS environment variable must be set. Cannot start without a password.")
}
if err := authService.EnsureDefaultUser(defaultUser, defaultPass); err != nil {
log.Printf("Warning: failed to ensure default user: %v", err)
@@ -112,12 +109,16 @@ func main() {
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(middleware.Timeout(60 * time.Second))
- r.Use(sessionManager.LoadAndSave) // Session middleware must be applied globally
- r.Use(authHandlers.Middleware().CSRFProtect) // CSRF protection
+ r.Use(appmiddleware.SecurityHeaders(cfg.Debug)) // Security headers
+ r.Use(sessionManager.LoadAndSave) // Session middleware must be applied globally
+ r.Use(authHandlers.Middleware().CSRFProtect) // CSRF protection
+
+ // Rate limiter for auth endpoints (5 requests per 15 minutes per IP)
+ authRateLimiter := appmiddleware.NewRateLimiter(5, 15*time.Minute)
// Public routes (no auth required)
r.Get("/login", authHandlers.HandleLoginPage)
- r.Post("/login", authHandlers.HandleLogin)
+ r.With(authRateLimiter.Limit).Post("/login", authHandlers.HandleLogin)
r.Post("/logout", authHandlers.HandleLogout)
// Serve static files (public)