65 lines
1.9 KiB
Go
65 lines
1.9 KiB
Go
// Package securelog centralizes log hygiene for secrets.
|
|
//
|
|
// Policy:
|
|
// - Never log password / new_password / current_password / temporary_password
|
|
// - Never log password_hash, refresh_token, access_token, api keys
|
|
// - go-zero mon dumps full Mongo docs at info — call SilenceMongo() at process start
|
|
package securelog
|
|
|
|
import (
|
|
"encoding/json"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/zeromicro/go-zero/core/stores/mon"
|
|
)
|
|
|
|
// sensitiveJSONKeys matched case-insensitively as JSON object keys.
|
|
var sensitiveKeyPattern = regexp.MustCompile(
|
|
`(?i)("(?:password|new_password|current_password|temporary_password|password_hash|` +
|
|
`access_token|refresh_token|api_key|secret|authorization|cookie)"\s*:\s*)` +
|
|
`(?:"(?:\\.|[^"\\])*"|null|true|false|-?\d+(?:\.\d+)?)`,
|
|
)
|
|
|
|
// SilenceMongo disables go-zero mon command logging (including document dumps).
|
|
// monc uses mon under the hood; without this, ReplaceOne logs password_hash.
|
|
func SilenceMongo() {
|
|
mon.DisableLog()
|
|
}
|
|
|
|
// RedactJSON replaces known secret fields in a JSON blob with "[REDACTED]".
|
|
func RedactJSON(raw string) string {
|
|
if raw == "" {
|
|
return raw
|
|
}
|
|
return sensitiveKeyPattern.ReplaceAllString(raw, `${1}"[REDACTED]"`)
|
|
}
|
|
|
|
// RedactAny marshals v then redacts; for ad-hoc logx of structs.
|
|
func RedactAny(v any) string {
|
|
if v == nil {
|
|
return "null"
|
|
}
|
|
b, err := json.Marshal(v)
|
|
if err != nil {
|
|
return "[unserializable]"
|
|
}
|
|
return RedactJSON(string(b))
|
|
}
|
|
|
|
// MaskPassword returns a fixed placeholder (never the input).
|
|
func MaskPassword(_ string) string { return "[REDACTED]" }
|
|
|
|
// IsSensitiveKey reports if a field name must never be logged.
|
|
func IsSensitiveKey(name string) bool {
|
|
n := strings.ToLower(strings.TrimSpace(name))
|
|
switch n {
|
|
case "password", "new_password", "current_password", "temporary_password",
|
|
"password_hash", "access_token", "refresh_token", "api_key", "secret",
|
|
"authorization", "cookie", "content": // media content is base64 blob
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|