auth: the duplicate-cookie line hides a link's token (audit A4)
Security audit 2026-10-17, finding A4 (low), stage 0. The line logged when a request carries two unprefixed session cookies printed r.URL.Path raw, so GET /confirm/<token> wrote the token to the log (reachable only with PANEL_COOKIE_SECURE=false, where a sibling host can plant the bare name). loggedPath moves from internal/web to internal/web/auth as LoggedPath (web imports auth, not the other way) and both lines - the origin check's refusal and the duplicate-cookie one - go through it. Tests: TestDuplicateCookieLineHidesALinksToken; TestLoggedPathHidesTokens moved with the function. go test ./internal/web ./internal/web/auth. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -400,3 +400,17 @@ func loginInfo(r *http.Request) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// LoggedPath is a request's path as the log may hold it: the token of a
|
||||
// password-reset or confirmation link is a secret, and the log is read by
|
||||
// more than the person the link went to (security review, 2026-10-17).
|
||||
// Every log line that names a request's path goes through it: the origin
|
||||
// check's refusal and the duplicate-cookie line (audit 2026-10-17, A4).
|
||||
func LoggedPath(p string) string {
|
||||
for _, prefix := range []string{"/login/reset/", "/confirm/"} {
|
||||
if strings.HasPrefix(p, prefix) && len(p) > len(prefix) {
|
||||
return prefix + "…"
|
||||
}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user