start working on the frontend side
This commit is contained in:
102
backend/internal/common/router/security.go
Normal file
102
backend/internal/common/router/security.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"github.com/atlasos/calypso/internal/common/config"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// securityHeadersMiddleware adds security headers to responses
|
||||
func securityHeadersMiddleware(cfg *config.Config) gin.HandlerFunc {
|
||||
if !cfg.Security.SecurityHeaders.Enabled {
|
||||
return func(c *gin.Context) {
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
return func(c *gin.Context) {
|
||||
// Prevent clickjacking
|
||||
c.Header("X-Frame-Options", "DENY")
|
||||
|
||||
// Prevent MIME type sniffing
|
||||
c.Header("X-Content-Type-Options", "nosniff")
|
||||
|
||||
// Enable XSS protection
|
||||
c.Header("X-XSS-Protection", "1; mode=block")
|
||||
|
||||
// Strict Transport Security (HSTS) - only if using HTTPS
|
||||
// c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
|
||||
|
||||
// Content Security Policy (basic)
|
||||
c.Header("Content-Security-Policy", "default-src 'self'")
|
||||
|
||||
// Referrer Policy
|
||||
c.Header("Referrer-Policy", "strict-origin-when-cross-origin")
|
||||
|
||||
// Permissions Policy
|
||||
c.Header("Permissions-Policy", "geolocation=(), microphone=(), camera=()")
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// corsMiddleware creates configurable CORS middleware
|
||||
func corsMiddleware(cfg *config.Config) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
origin := c.Request.Header.Get("Origin")
|
||||
|
||||
// Check if origin is allowed
|
||||
allowed := false
|
||||
for _, allowedOrigin := range cfg.Security.CORS.AllowedOrigins {
|
||||
if allowedOrigin == "*" || allowedOrigin == origin {
|
||||
allowed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if allowed {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
|
||||
}
|
||||
|
||||
if cfg.Security.CORS.AllowCredentials {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
}
|
||||
|
||||
// Set allowed methods
|
||||
methods := cfg.Security.CORS.AllowedMethods
|
||||
if len(methods) == 0 {
|
||||
methods = []string{"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"}
|
||||
}
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", joinStrings(methods, ", "))
|
||||
|
||||
// Set allowed headers
|
||||
headers := cfg.Security.CORS.AllowedHeaders
|
||||
if len(headers) == 0 {
|
||||
headers = []string{"Content-Type", "Authorization", "Accept", "Origin"}
|
||||
}
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", joinStrings(headers, ", "))
|
||||
|
||||
// Handle preflight requests
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.AbortWithStatus(204)
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// joinStrings joins a slice of strings with a separator
|
||||
func joinStrings(strs []string, sep string) string {
|
||||
if len(strs) == 0 {
|
||||
return ""
|
||||
}
|
||||
if len(strs) == 1 {
|
||||
return strs[0]
|
||||
}
|
||||
result := strs[0]
|
||||
for _, s := range strs[1:] {
|
||||
result += sep + s
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user