Files
trufflehog/pkg/log/dynamic_redactor.go
Cody Rose f42f63271b Create global log redaction capability (#3522)
Some source use client libraries that can emit errors that contain sensitive information - in particular, git-facing libraries that embed tokens into repository URLs. This PR introduces a way of redacting them - starting with GitLab (where we've seen this most recently), but in theory extensible to other sources as needed.

This implementation uses a custom zap core; this might also be possible with a custom zap encoder, but I didn't test it out.

(The deleted core.go file was entirely unused.)
2024-10-29 09:44:07 -04:00

51 lines
1.2 KiB
Go

package log
import (
"strings"
"sync"
"sync/atomic"
)
type dynamicRedactor struct {
denySet map[string]struct{}
denySlice []string
denyMu sync.Mutex
replacer atomic.Pointer[strings.Replacer]
}
var globalRedactor *dynamicRedactor
func init() {
globalRedactor = &dynamicRedactor{denySet: make(map[string]struct{})}
globalRedactor.replacer.CompareAndSwap(nil, strings.NewReplacer())
}
// RedactGlobally configures the global log redactor to redact the provided value during log emission. The value will be
// redacted in log messages and values that are strings, but not in log keys or values of other types.
func RedactGlobally(sensitiveValue string) {
globalRedactor.configureForRedaction(sensitiveValue)
}
func (r *dynamicRedactor) configureForRedaction(sensitiveValue string) {
if sensitiveValue == "" {
return
}
r.denyMu.Lock()
defer r.denyMu.Unlock()
if _, ok := r.denySet[sensitiveValue]; ok {
return
}
r.denySet[sensitiveValue] = struct{}{}
r.denySlice = append(r.denySlice, sensitiveValue, "*****")
r.replacer.Store(strings.NewReplacer(r.denySlice...))
}
func (r *dynamicRedactor) redact(s string) string {
return r.replacer.Load().Replace(s)
}