From 53123c0b015872754cdb35ec99e1fd4cba90aaba Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Mon, 13 Nov 2023 20:37:29 +0100 Subject: [PATCH] lib/api: Improve cookie handling (fixes #9208) (#9214) --- lib/api/api_auth.go | 52 +++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/lib/api/api_auth.go b/lib/api/api_auth.go index 1dfaeee0f..7f9610068 100644 --- a/lib/api/api_auth.go +++ b/lib/api/api_auth.go @@ -85,14 +85,19 @@ func basicAuthAndSessionMiddleware(cookieName string, guiCfg config.GUIConfigura return } - cookie, err := r.Cookie(cookieName) - if err == nil && cookie != nil { - sessionsMut.Lock() - _, ok := sessions[cookie.Value] - sessionsMut.Unlock() - if ok { - next.ServeHTTP(w, r) - return + for _, cookie := range r.Cookies() { + // We iterate here since there may, historically, be multiple + // cookies with the same name but different path. Any "old" ones + // won't match an existing session and will be ignored, then + // later removed on logout or when timing out. + if cookie.Name == cookieName { + sessionsMut.Lock() + _, ok := sessions[cookie.Value] + sessionsMut.Unlock() + if ok { + next.ServeHTTP(w, r) + return + } } } @@ -198,21 +203,26 @@ func createSession(cookieName string, username string, guiCfg config.GUIConfigur func handleLogout(cookieName string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - cookie, err := r.Cookie(cookieName) - if err == nil && cookie != nil { - sessionsMut.Lock() - delete(sessions, cookie.Value) - sessionsMut.Unlock() + for _, cookie := range r.Cookies() { + // We iterate here since there may, historically, be multiple + // cookies with the same name but different path. We drop them + // all. + if cookie.Name == cookieName { + sessionsMut.Lock() + delete(sessions, cookie.Value) + sessionsMut.Unlock() + + // Delete the cookie + http.SetCookie(w, &http.Cookie{ + Name: cookieName, + Value: "", + MaxAge: -1, + Secure: cookie.Secure, + Path: cookie.Path, + }) + } } - // else: If there is no session cookie, that's also a successful logout in terms of user experience. - http.SetCookie(w, &http.Cookie{ - Name: cookieName, - Value: "", - MaxAge: -1, - Secure: true, - Path: "/", - }) w.WriteHeader(http.StatusNoContent) }) }