fix: 修复4个安全漏洞 (HIGH-01, HIGH-02, MED-01, MED-02)

- HIGH-01: CheckScope空scope绕过权限检查
  * 修复: 空scope现在返回false拒绝访问

- HIGH-02: JWT算法验证不严格
  * 修复: 使用token.Method.Alg()严格验证只接受HS256

- MED-01: RequireAnyScope空scope列表逻辑错误
  * 修复: 空列表现在返回403拒绝访问

- MED-02: Token状态缓存未命中时默认返回active
  * 修复: 添加TokenStatusBackend接口,缓存未命中时必须查询后端

影响文件:
- supply-api/internal/iam/middleware/scope_auth.go
- supply-api/internal/middleware/auth.go
- supply-api/cmd/supply-api/main.go (适配新API)

测试覆盖:
- 添加4个新的安全测试用例
- 更新1个原有测试以反映正确的安全行为
This commit is contained in:
Your Name
2026-04-03 07:52:41 +08:00
parent 90490ce86d
commit 50225f6822
5 changed files with 300 additions and 66 deletions

View File

@@ -34,9 +34,15 @@ type AuthConfig struct {
// AuthMiddleware 鉴权中间件
type AuthMiddleware struct {
config AuthConfig
tokenCache *TokenCache
auditEmitter AuditEmitter
config AuthConfig
tokenCache *TokenCache
tokenBackend TokenStatusBackend
auditEmitter AuditEmitter
}
// TokenStatusBackend Token状态后端查询接口
type TokenStatusBackend interface {
CheckTokenStatus(ctx context.Context, tokenID string) (string, error)
}
// AuditEmitter 审计事件发射器
@@ -57,13 +63,14 @@ type AuditEvent struct {
}
// NewAuthMiddleware 创建鉴权中间件
func NewAuthMiddleware(config AuthConfig, tokenCache *TokenCache, auditEmitter AuditEmitter) *AuthMiddleware {
func NewAuthMiddleware(config AuthConfig, tokenCache *TokenCache, tokenBackend TokenStatusBackend, auditEmitter AuditEmitter) *AuthMiddleware {
if config.CacheTTL == 0 {
config.CacheTTL = 30 * time.Second
}
return &AuthMiddleware{
config: config,
tokenCache: tokenCache,
tokenBackend: tokenBackend,
auditEmitter: auditEmitter,
}
}
@@ -298,7 +305,8 @@ func (m *AuthMiddleware) ScopeRoleAuthzMiddleware(requiredScope string) func(htt
// verifyToken 校验JWT token
func (m *AuthMiddleware) verifyToken(tokenString string) (*TokenClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &TokenClaims{}, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
// 严格验证算法只接受HS256
if token.Method.Alg() != jwt.SigningMethodHS256.Alg() {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return []byte(m.config.SecretKey), nil
@@ -339,8 +347,13 @@ func (m *AuthMiddleware) checkTokenStatus(tokenID string) (string, error) {
}
}
// 缓存未命中,返回active实际应该查询数据库
return "active", nil
// 缓存未命中,查询后端验证token状态
if m.tokenBackend != nil {
return m.tokenBackend.CheckTokenStatus(context.Background(), tokenID)
}
// 没有后端实现时应该拒绝访问而不是默认active
return "", errors.New("token status unknown: backend not configured")
}
// GetTokenClaims 从context获取token claims