Files
junhong_cmp_fiber/pkg/sanitizer/sanitizer.go
break b3499adfca 固化七月迭代审计治理进展以隔离线上热修
Constraint: 切换 main 前必须保存当前七月分支全部项目进展,套餐生效提案仅属于 Iteration/7-11。

Rejected: 将七月套餐修复直接移植到 main | 两个分支的可靠投递架构不同。

Confidence: medium

Scope-risk: broad

Directive: 不得将本提交整体 cherry-pick 到 main;main 套餐热修必须基于其纯 Asynq 代码独立实施。

Tested: git diff --check;openspec validate fix-package-activation-starvation --strict。

Not-tested: 按用户要求未运行自动化测试;go build ./... 因当前审计改造中的 Enterprise 模型字面量和 role.recordFailure 参数类型错误未通过。
2026-08-03 09:47:22 +08:00

80 lines
2.2 KiB
Go

// Package sanitizer 提供 Access、Audit 与 Integration 共用的敏感字段清理能力。
package sanitizer
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"strings"
"github.com/bytedance/sonic"
)
var forbiddenFragments = []string{
"password", "passwd", "credential", "operation_password", "verification_code", "captcha",
"access_token", "refresh_token", "authorization", "cookie", "secret", "private_key", "public_key",
"encoding_aes_key", "callback_token", "signature", "sign", "nonce", "media_id", "signed_url",
"private_url", "qr_content", "id_card", "identity_number",
}
// IsForbiddenField 判断字段是否禁止进入普通日志、审计或外部交互摘要。
func IsForbiddenField(key string) bool {
normalized := strings.ToLower(strings.NewReplacer("-", "_", ".", "_").Replace(key))
if normalized == "credentials_configured" {
return false
}
for _, fragment := range forbiddenFragments {
if strings.Contains(normalized, fragment) {
return true
}
}
if strings.HasSuffix(normalized, "_key") || normalized == "key" || strings.HasSuffix(normalized, "_url") || normalized == "url" {
return true
}
return false
}
// MarshalSummary 递归删除禁止字段并返回 sonic 编码的安全 JSON。
func MarshalSummary(value any) ([]byte, error) {
if value == nil {
return nil, nil
}
encoded, err := sonic.Marshal(value)
if err != nil {
return nil, err
}
var normalized any
if err := sonic.Unmarshal(encoded, &normalized); err != nil {
return nil, err
}
RemoveForbiddenFields(normalized)
return sonic.Marshal(normalized)
}
// RemoveForbiddenFields 原地递归删除 Map 或数组中的禁止字段。
func RemoveForbiddenFields(value any) {
switch typed := value.(type) {
case map[string]any:
for key, item := range typed {
if IsForbiddenField(key) {
delete(typed, key)
continue
}
RemoveForbiddenFields(item)
}
case []any:
for _, item := range typed {
RemoveForbiddenFields(item)
}
}
}
// TextSummary 将不可信外部文本转换为不可逆大小和哈希摘要。
func TextSummary(value string) string {
if value == "" {
return ""
}
sum := sha256.Sum256([]byte(value))
return fmt.Sprintf("外部文本摘要 bytes=%d sha256=%s", len(value), hex.EncodeToString(sum[:8]))
}