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:
@@ -3,9 +3,11 @@ package auth
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -88,6 +90,24 @@ func TestSessionTokenRejectsDuplicates(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The duplicate-cookie line names the request's path, and a link's token is
|
||||
// not written to the log with it (audit 2026-10-17, A4).
|
||||
func TestDuplicateCookieLineHidesALinksToken(t *testing.T) {
|
||||
m := testModule(t, false)
|
||||
var buf strings.Builder
|
||||
log.SetOutput(&buf)
|
||||
t.Cleanup(func() { log.SetOutput(os.Stderr) })
|
||||
r := httptest.NewRequest(http.MethodGet, "http://panel.example.com/confirm/the-secret-token-of-a-link", nil)
|
||||
r.AddCookie(&http.Cookie{Name: "selfpost_session", Value: "planted-by-a-neighbour"})
|
||||
r.AddCookie(&http.Cookie{Name: "selfpost_session", Value: "the-real-session"})
|
||||
if _, ok := m.sessionToken(r); ok {
|
||||
t.Fatal("duplicate cookies accepted")
|
||||
}
|
||||
if got := buf.String(); strings.Contains(got, "the-secret-token-of-a-link") || !strings.Contains(got, "GET /confirm/… carries 2 cookies") {
|
||||
t.Errorf("logged %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSessionTokenReadsOneCookie(t *testing.T) {
|
||||
m := testModule(t, true)
|
||||
r := httptest.NewRequest(http.MethodGet, "http://panel.example.com/domains", nil)
|
||||
|
||||
Reference in New Issue
Block a user