Implement CSRF protection middleware with configurable secret and cookie options
This commit is contained in:
38
cmd/start.go
38
cmd/start.go
@ -2,6 +2,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
@ -51,6 +52,39 @@ var startCmd = &cobra.Command{
|
||||
|
||||
// Create CORS configuration
|
||||
corsConfig := middleware.DefaultCORSConfig()
|
||||
|
||||
// Start with minimal default configuration
|
||||
csrfConfig := middleware.DefaultCSRFConfig()
|
||||
|
||||
// Set CSRF secret from config or generate a random one
|
||||
csrfSecret := viper.GetString("csrf-secret")
|
||||
var csrfKey []byte
|
||||
|
||||
if csrfSecret != "" {
|
||||
// Use configured secret - must be at least 32 bytes
|
||||
csrfKey = []byte(csrfSecret)
|
||||
if len(csrfKey) < 32 {
|
||||
logger.Error("csrf-secret must be at least 32 bytes")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// Generate a random secret
|
||||
csrfKey = make([]byte, 32)
|
||||
_, err = rand.Read(csrfKey)
|
||||
if err != nil {
|
||||
logger.Error("failed to generate CSRF key", slog.Any("error", err))
|
||||
return
|
||||
}
|
||||
logger.Info("generated random CSRF key, consider setting csrf-secret for stability across restarts")
|
||||
}
|
||||
|
||||
csrfConfig.Secret = csrfKey
|
||||
|
||||
// Only override specific settings when needed
|
||||
if env == "development" {
|
||||
// In development, cookies often need to work without HTTPS
|
||||
csrfConfig.Cookie.Secure = false
|
||||
}
|
||||
|
||||
// Create middleware stack
|
||||
stack := middleware.CreateStack(
|
||||
@ -61,6 +95,7 @@ var startCmd = &cobra.Command{
|
||||
middleware.MaxBodySize(1024*1024), // 1MB size limit
|
||||
middleware.SecureHeaders(), // Set secure headers
|
||||
middleware.CORS(corsConfig), // CORS configuration
|
||||
middleware.CSRF(csrfConfig), // CSRF protection
|
||||
authConfig.Middleware(), // OIDC authentication middleware
|
||||
)
|
||||
|
||||
@ -99,6 +134,7 @@ func init() {
|
||||
startCmd.Flags().String("issuer-url", "", "Identity Provider Issuer URL")
|
||||
startCmd.Flags().String("hostname", "", "Address at which the server is exposed")
|
||||
startCmd.Flags().String("session-secret", "", "Session encryption secret")
|
||||
startCmd.Flags().String("csrf-secret", "", "Secret key for CSRF protection (min 32 bytes)")
|
||||
startCmd.Flags().String("env", "", "Environment (development/production)")
|
||||
|
||||
// Bind all flags to Viper
|
||||
@ -110,4 +146,4 @@ func init() {
|
||||
|
||||
// Add the command to the root command
|
||||
rootCmd.AddCommand(startCmd)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user