mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-08-30 06:30:41 +02:00
Add files via upload
This commit is contained in:
+54
-6
@@ -84,7 +84,7 @@ func New(cfg *config.Config, log *logger.Logger, configPath string) (*App, error
|
||||
router := gin.Default()
|
||||
|
||||
// CORS中间件
|
||||
router.Use(corsMiddleware())
|
||||
router.Use(corsMiddleware(cfg.Server.CORSAllowedOrigins))
|
||||
|
||||
// 初始化数据库
|
||||
dbPath := cfg.Database.Path
|
||||
@@ -2069,22 +2069,36 @@ func initializeKnowledge(
|
||||
return knowledgeHandler, nil
|
||||
}
|
||||
|
||||
// corsMiddleware CORS中间件
|
||||
func corsMiddleware() gin.HandlerFunc {
|
||||
// corsMiddleware allows same-origin requests, valid Chromium extension
|
||||
// origins, and exact origins explicitly configured by the operator. CORS is
|
||||
// not an authentication boundary; API access still requires a valid session.
|
||||
func corsMiddleware(configuredOrigins []string) gin.HandlerFunc {
|
||||
allowedOrigins := make(map[string]struct{}, len(configuredOrigins))
|
||||
for _, origin := range configuredOrigins {
|
||||
if normalized, ok := normalizeCORSOrigin(origin); ok {
|
||||
allowedOrigins[normalized] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
return func(c *gin.Context) {
|
||||
origin := strings.TrimSpace(c.GetHeader("Origin"))
|
||||
if origin != "" {
|
||||
parsed, err := url.Parse(origin)
|
||||
if err != nil || parsed.Host == "" || !strings.EqualFold(parsed.Host, c.Request.Host) {
|
||||
c.Writer.Header().Add("Vary", "Origin")
|
||||
normalized, valid := normalizeCORSOrigin(origin)
|
||||
_, explicitlyAllowed := allowedOrigins[normalized]
|
||||
parsed, _ := url.Parse(origin)
|
||||
sameHost := valid && strings.EqualFold(parsed.Host, c.Request.Host)
|
||||
browserExtension := valid && isChromiumExtensionOrigin(parsed)
|
||||
if !sameHost && !browserExtension && !explicitlyAllowed {
|
||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "cross-origin request denied"})
|
||||
return
|
||||
}
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
|
||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
c.Writer.Header().Add("Vary", "Origin")
|
||||
}
|
||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
|
||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
|
||||
c.Writer.Header().Set("Access-Control-Max-Age", "600")
|
||||
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.AbortWithStatus(204)
|
||||
@@ -2094,3 +2108,37 @@ func corsMiddleware() gin.HandlerFunc {
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// isChromiumExtensionOrigin accepts only Chrome's canonical 32-character
|
||||
// extension IDs (letters a-p). It does not allow arbitrary custom schemes or
|
||||
// web origins, and the extension must separately obtain host permission.
|
||||
func isChromiumExtensionOrigin(origin *url.URL) bool {
|
||||
if origin == nil || !strings.EqualFold(origin.Scheme, "chrome-extension") || origin.Port() != "" {
|
||||
return false
|
||||
}
|
||||
id := strings.ToLower(origin.Hostname())
|
||||
if len(id) != 32 {
|
||||
return false
|
||||
}
|
||||
for _, ch := range id {
|
||||
if ch < 'a' || ch > 'p' {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// normalizeCORSOrigin validates and canonicalizes a serialized origin. CORS
|
||||
// origins never contain credentials, paths, query strings, or fragments.
|
||||
func normalizeCORSOrigin(raw string) (string, bool) {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" || raw == "*" || strings.EqualFold(raw, "null") {
|
||||
return "", false
|
||||
}
|
||||
parsed, err := url.Parse(raw)
|
||||
if err != nil || parsed.Scheme == "" || parsed.Host == "" || parsed.User != nil ||
|
||||
(parsed.Path != "" && parsed.Path != "/") || parsed.RawQuery != "" || parsed.Fragment != "" {
|
||||
return "", false
|
||||
}
|
||||
return strings.ToLower(parsed.Scheme) + "://" + strings.ToLower(parsed.Host), true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user