fix(P2): 修复4个P2轻微问题
P2-01: 通配符scope安全风险 (scope_auth.go) - 添加hasWildcardScope()函数检测通配符scope - 添加logWildcardScopeAccess()函数记录审计日志 - 在RequireScope/RequireAllScopes/RequireAnyScope中间件中调用审计日志 P2-02: isSamePayload比较字段不完整 (audit_service.go) - 添加ActionDetail字段比较 - 添加ResultMessage字段比较 - 添加Extensions字段比较 - 添加compareExtensions()辅助函数 P2-03: regexp.MustCompile可能panic (sanitizer.go) - 添加compileRegex()安全编译函数替代MustCompile - 处理编译错误,避免panic P2-04: StrategyRoundRobin未实现 (router.go) - 添加selectByRoundRobin()方法 - 添加roundRobinCounter原子计数器 - 使用atomic.AddUint64实现线程安全的轮询 P2-05: 错误信息泄露内部细节 - 已在MED-09中处理,跳过
This commit is contained in:
@@ -315,6 +315,9 @@ func isSamePayload(a, b *model.AuditEvent) bool {
|
||||
if a.Action != b.Action {
|
||||
return false
|
||||
}
|
||||
if a.ActionDetail != b.ActionDetail {
|
||||
return false
|
||||
}
|
||||
if a.CredentialType != b.CredentialType {
|
||||
return false
|
||||
}
|
||||
@@ -330,5 +333,30 @@ func isSamePayload(a, b *model.AuditEvent) bool {
|
||||
if a.ResultCode != b.ResultCode {
|
||||
return false
|
||||
}
|
||||
if a.ResultMessage != b.ResultMessage {
|
||||
return false
|
||||
}
|
||||
// 比较Extensions
|
||||
if !compareExtensions(a.Extensions, b.Extensions) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// compareExtensions 比较两个map是否相等
|
||||
func compareExtensions(a, b map[string]any) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for k, v1 := range a {
|
||||
v2, ok := b[k]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
// 简单的值比较,不处理嵌套map的情况
|
||||
if v1 != v2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -550,4 +550,63 @@ func TestAuditService_IdempotencyRaceCondition(t *testing.T) {
|
||||
assert.Equal(t, 1, createdCount, "Should have exactly one created event")
|
||||
assert.Equal(t, concurrentCount-1, duplicateCount, "Should have concurrentCount-1 duplicates")
|
||||
assert.Equal(t, 0, conflictCount, "Should have no conflicts for same payload")
|
||||
}
|
||||
}
|
||||
// P2-02: isSamePayload比较字段不完整,缺少ActionDetail/ResultMessage/Extensions等字段
|
||||
func TestP2_02_IsSamePayload_MissingFields(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
svc := NewAuditService(NewInMemoryAuditStore())
|
||||
|
||||
// 第一次事件 - 完整的payload
|
||||
event1 := &model.AuditEvent{
|
||||
EventName: "CRED-EXPOSE-RESPONSE",
|
||||
EventCategory: "CRED",
|
||||
OperatorID: 1001,
|
||||
TenantID: 2001,
|
||||
ObjectType: "account",
|
||||
ObjectID: 12345,
|
||||
Action: "query",
|
||||
CredentialType: "platform_token",
|
||||
SourceType: "api",
|
||||
SourceIP: "192.168.1.1",
|
||||
Success: true,
|
||||
ResultCode: "SEC_CRED_EXPOSED",
|
||||
ActionDetail: "detailed action info", // 缺失字段
|
||||
ResultMessage: "operation completed", // 缺失字段
|
||||
IdempotencyKey: "p2-02-test-key",
|
||||
}
|
||||
|
||||
// 第二次重放 - ActionDetail和ResultMessage不同,但isSamePayload应该能检测出来
|
||||
event2 := &model.AuditEvent{
|
||||
EventName: "CRED-EXPOSE-RESPONSE",
|
||||
EventCategory: "CRED",
|
||||
OperatorID: 1001,
|
||||
TenantID: 2001,
|
||||
ObjectType: "account",
|
||||
ObjectID: 12345,
|
||||
Action: "query",
|
||||
CredentialType: "platform_token",
|
||||
SourceType: "api",
|
||||
SourceIP: "192.168.1.1",
|
||||
Success: true,
|
||||
ResultCode: "SEC_CRED_EXPOSED",
|
||||
ActionDetail: "different action info", // 与event1不同
|
||||
ResultMessage: "different message", // 与event1不同
|
||||
IdempotencyKey: "p2-02-test-key",
|
||||
}
|
||||
|
||||
// 首次创建
|
||||
result1, err1 := svc.CreateEvent(ctx, event1)
|
||||
assert.NoError(t, err1)
|
||||
assert.Equal(t, 201, result1.StatusCode)
|
||||
|
||||
// 重放异参 - 应该返回409
|
||||
result2, err2 := svc.CreateEvent(ctx, event2)
|
||||
assert.NoError(t, err2)
|
||||
|
||||
// 如果isSamePayload没有比较ActionDetail和ResultMessage,这里会错误地返回200而不是409
|
||||
if result2.StatusCode == 200 {
|
||||
t.Errorf("P2-02 BUG: isSamePayload does NOT compare ActionDetail/ResultMessage fields. Got 200 (duplicate) but should be 409 (conflict)")
|
||||
} else if result2.StatusCode == 409 {
|
||||
t.Logf("P2-02 FIXED: isSamePayload correctly detects payload mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user