mirror of
https://github.com/navidrome/navidrome.git
synced 2026-10-21 00:37:09 +02:00
fix(log): redact marked secrets in every field type
redactSecrets only looked at strings, maps and errors, so a marked secret inside a slice, struct or []byte field was logged as is, and a typed-nil error field made it panic. It now renders each field with fmt.Sprint, as the text formatter does (which also survives typed-nil errors), and writes []byte raw. Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
parent
d3a434a610
commit
58090b42ec
2 changed files with 25 additions and 10 deletions
|
|
@ -83,18 +83,12 @@ func redactSecrets(e *logrus.Entry) {
|
|||
if v == nil {
|
||||
continue
|
||||
}
|
||||
// fmt.Sprint renders like the text formatter and survives typed-nil errors; []byte is written raw.
|
||||
var s string
|
||||
if err, ok := v.(error); ok {
|
||||
s = err.Error()
|
||||
if b, ok := v.([]byte); ok {
|
||||
s = string(b)
|
||||
} else {
|
||||
switch reflect.TypeOf(v).Kind() {
|
||||
case reflect.String:
|
||||
s = reflect.ValueOf(v).String()
|
||||
case reflect.Map:
|
||||
s = fmt.Sprintf("%+v", v)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
s = fmt.Sprint(v)
|
||||
}
|
||||
if hidden := hide(s); hidden != s {
|
||||
e.Data[k] = hidden
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package log
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
|
@ -196,6 +197,26 @@ func TestFireRedactsContextSecrets(t *testing.T) {
|
|||
assert.Equal(t, namedString("untouched"), e.Data["clean"])
|
||||
}
|
||||
|
||||
func TestFireRedactsContextSecretsInAnyValueType(t *testing.T) {
|
||||
ctx := WithSecrets(t.Context(), "s3cr3t-value")
|
||||
var nilErr *url.Error
|
||||
e := &logrus.Entry{
|
||||
Context: ctx,
|
||||
Data: logrus.Fields{
|
||||
"slice": []any{"s3cr3t-value", 1},
|
||||
"struct": struct{ A string }{"s3cr3t-value"},
|
||||
"bytes": []byte("has s3cr3t-value"),
|
||||
"nilErr": nilErr,
|
||||
},
|
||||
}
|
||||
|
||||
assert.NotPanics(t, func() { _ = (&Hook{}).Fire(e) })
|
||||
assert.Equal(t, "[[REDACTED] 1]", e.Data["slice"])
|
||||
assert.Equal(t, "{[REDACTED]}", e.Data["struct"])
|
||||
assert.Equal(t, "has [REDACTED]", e.Data["bytes"])
|
||||
assert.Equal(t, nilErr, e.Data["nilErr"])
|
||||
}
|
||||
|
||||
func TestFireWithoutContextSecretsLeavesEntryUnchanged(t *testing.T) {
|
||||
args := map[string]any{"p0": "value"}
|
||||
e := &logrus.Entry{Context: t.Context(), Message: "value", Data: logrus.Fields{"str": "value", "args": args}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue