You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Address four substantive review findings on the contextual-logs work.
1. log/default.go writeContext error sanitization (Copilot)
The render-error marker piped err.Error() through fmt.Fprintf, which
could carry CR/LF/ANSI bytes from a tag wrapping attacker-controlled
data. Route the message through writeSanitizedString — the same
sanitiser ${value:KEY} already uses — so a misconfigured tag cannot
become a log-injection vector. Test_WithContextRenderError now embeds
CR/LF in the error and asserts they are stripped.
2. docs/api/log.md KeyValueFormat consistency (Copilot)
Both the Go-block snippet and the Context Formats table referenced
the bare ${requestid} tag while the actual KeyValueFormat constant
uses the dashed ${request-id} alias. Align both to the constant.
3. log/default.go newRetainedContext typed-nil handling (CodeRabbit)
`value != nil` does not catch typed nils such as
`(*fasthttp.RequestCtx)(nil)` stored in an `any`; the interface
header carries a non-nil type descriptor and the renderer would
dereference a nil receiver. Use reflect.Value.IsNil() on the
nilable kinds (Chan, Func, Interface, Map, Pointer, Slice) to
collapse typed nils to retainedContext{}. Reflection runs once per
WithContext call (not per log line), so the cost is irrelevant to
the hot path. Test_NewRetainedContext_TypedNil locks in coverage
for untyped nil, typed-nil pointer/map/slice/chan, and non-nil
variants of the same.
4. middleware/csrf csrf-token redaction shape (CodeRabbit)
Switch the csrf-token tag from the package-local "[redacted]"
constant to redact.Prefix(token), aligning the masking shape with
keyauth and session (4-byte clear prefix + "****"). Log consumers
now see a uniform redaction format across every security-sensitive
tag the framework registers. csrf_test assertions move from exact
match against redactedKey to shape-based assertions on the
redact.Mask suffix. The package-internal redactedKey constant is
retained for storage-manager redaction (unchanged behavior).
Also document the intentional-by-design decisions:
- middleware/basicauth basicauth.go: ${username} is written in clear
text for audit-log use cases. Add a godoc block on
registerLogContextTags pointing developers to UsernameFromContext if
full usernames count as PII in their jurisdiction. Mirror the
callout in docs/api/log.md.
Verified locally with golangci-lint v2.6.0 (CI-matching), modernize@latest,
and `go test -race -shuffle=on` on the affected packages.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|`RequestIDFormat`|`"[${requestid}] "`| Prepends the request ID when the requestid middleware is used. |
285
-
|`KeyValueFormat`|`"request-id=${requestid} username=${username} api-key=${api-key} csrf-token=${csrf-token} session-id=${session-id} "`| Prepends common middleware context values as key/value fields. Sensitive values are redacted by the registering middleware. |
285
+
|`KeyValueFormat`|`"request-id=${request-id} username=${username} api-key=${api-key} csrf-token=${csrf-token} session-id=${session-id} "`| Prepends common middleware context values as key/value fields. Sensitive values are redacted by the registering middleware. |
0 commit comments