fix(log): redact named string types instead of panicking

The redaction hook matched fields by reflect.Kind but read them with a
v.(string) type assertion, so any named string type (such as an enum)
panicked the log call. API v1 problem logging hit this on every error.
This commit is contained in:
Deluan 2026-09-26 02:49:05 -04:00
commit d368eef3ce
3 changed files with 20 additions and 1 deletions

View file

@ -47,7 +47,8 @@ func (h *Hook) Fire(e *logrus.Entry) error {
}
switch reflect.TypeOf(v).Kind() {
case reflect.String:
e.Data[k] = re.ReplaceAllString(v.(string), "$1[REDACTED]$2")
// Via reflect: named string types (e.g. enums) have Kind String but fail v.(string).
e.Data[k] = re.ReplaceAllString(reflect.ValueOf(v).String(), "$1[REDACTED]$2")
continue
case reflect.Map:
s := fmt.Sprintf("%+v", v)

View file

@ -157,3 +157,14 @@ func TestEntryMessage(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, "Secret Password: [REDACTED]", logEntry.Message)
}
type namedString string
func TestFireRedactsNamedStringTypes(t *testing.T) {
hook := &Hook{RedactionList: []string{"(secret=)[^&]+"}}
e := &logrus.Entry{Data: logrus.Fields{"code": namedString("not_found"), "url": namedString("/x?secret=abc")}}
assert.NotPanics(t, func() { _ = hook.Fire(e) })
assert.Equal(t, "not_found", e.Data["code"])
assert.Equal(t, "/x?secret=[REDACTED]", e.Data["url"])
}

View file

@ -77,6 +77,13 @@ var _ = Describe("problem", func() {
Expect(*p.Errors).To(ConsistOf(ValidationError{Field: "currentPassword", Message: "is incorrect"}))
})
It("writes and logs a problem with debug logging on", func() {
logs := captureLogs()
writeProblem(w, r, model.ErrNotFound)
Expect(w.Code).To(Equal(http.StatusNotFound))
Expect(logs.String()).To(ContainSubstring("code=not_found"))
})
It("adds a Bearer challenge to every 401 unless one is already set", func() {
writeProblem(w, r, model.ErrInvalidAuth)
Expect(w.Header().Get("WWW-Authenticate")).To(Equal("Bearer"))