Files
2026-07-14 10:24:10 +08:00

49 lines
1.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package middleware
import (
"github.com/EthanCodeCraft/xlgo-core/utils"
"github.com/gin-gonic/gin"
)
// 请求 ID 校验约束(M15 修复:不无条件信任客户端 X-Request-ID,防头注入/日志伪造)。
const (
// requestIDMaxLen 客户端传入请求 ID 的最大长度。超长视为非法并重新生成,避免日志膨胀/注入。
requestIDMaxLen = 128
)
// sanitizeRequestID 校验客户端传入的 X-Request-ID:仅允许可见 ASCII0x20-0x7e)且
// 不含 CR/LF(防 HTTP 头注入与日志换行伪造),长度不超过 requestIDMaxLen。
// 非法或为空时返回 "",由调用方重新生成。
func sanitizeRequestID(id string) string {
if len(id) == 0 || len(id) > requestIDMaxLen {
return ""
}
for i := 0; i < len(id); i++ {
c := id[i]
if c < 0x20 || c > 0x7e {
return ""
}
}
return id
}
// RequestID 请求ID中间件,为每个请求生成唯一ID便于追踪。
//
// 客户端可经 X-Request-ID 头传入 ID 用于链路串联,但会做校验(M15 修复):
// 仅接受可见 ASCII、无换行、长度 ≤128 的值,否则忽略并重新生成——防头注入与日志伪造。
func RequestID() gin.HandlerFunc {
return func(c *gin.Context) {
requestID := sanitizeRequestID(c.GetHeader("X-Request-ID"))
if requestID == "" {
requestID = utils.UUID()
}
c.Set("request_id", requestID)
c.Header("X-Request-ID", requestID)
c.Next()
}
}
// GetRequestID 从上下文获取请求ID
func GetRequestID(c *gin.Context) string {
return c.GetString("request_id")
}