Preserve browser Origin on the confirmed sign-out form
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 35s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
This commit is contained in:
tegwick 2026-09-12 10:43:32 +02:00
parent 074c2ce498
commit 91efb6d988
2 changed files with 5 additions and 1 deletions

View file

@ -47,7 +47,8 @@ Applications that already have their own sessions may remain signed in.</p>
func (h *AccountLogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (h *AccountLogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-store") w.Header().Set("Cache-Control", "no-store")
w.Header().Set("Referrer-Policy", "no-referrer") // Keep the same-origin POST Origin; no-referrer makes Chromium send Origin: null.
w.Header().Set("Referrer-Policy", "same-origin")
w.Header().Set("Content-Security-Policy", "default-src 'none'; form-action 'self'; frame-ancestors 'none'; base-uri 'none'") w.Header().Set("Content-Security-Policy", "default-src 'none'; form-action 'self'; frame-ancestors 'none'; base-uri 'none'")
w.Header().Set("X-Content-Type-Options", "nosniff") w.Header().Set("X-Content-Type-Options", "nosniff")
switch r.Method { switch r.Method {

View file

@ -31,6 +31,9 @@ func TestSharedLogoutRequiresConfirmationAndFixedReturn(t *testing.T) {
if w.Code != 200 || w.Header().Get("Location") != "" { if w.Code != 200 || w.Header().Get("Location") != "" {
t.Fatal("GET must only confirm") t.Fatal("GET must only confirm")
} }
if w.Header().Get("Referrer-Policy") != "same-origin" {
t.Fatal("browser POST would lose its Origin")
}
c := w.Result().Cookies()[0] c := w.Result().Cookies()[0]
if !c.Secure || !c.HttpOnly || c.Domain != "" { if !c.Secure || !c.HttpOnly || c.Domain != "" {
t.Fatal("unsafe CSRF cookie") t.Fatal("unsafe CSRF cookie")