lib/api: Improve cookie handling (fixes #9208) (#9214)

This commit is contained in:
Jakob Borg 2023-11-13 20:37:29 +01:00 committed by GitHub
parent 0f8dc6c1d3
commit 8f1b0df74b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -85,8 +85,12 @@ func basicAuthAndSessionMiddleware(cookieName string, guiCfg config.GUIConfigura
return return
} }
cookie, err := r.Cookie(cookieName) for _, cookie := range r.Cookies() {
if err == nil && cookie != nil { // 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() sessionsMut.Lock()
_, ok := sessions[cookie.Value] _, ok := sessions[cookie.Value]
sessionsMut.Unlock() sessionsMut.Unlock()
@ -95,6 +99,7 @@ func basicAuthAndSessionMiddleware(cookieName string, guiCfg config.GUIConfigura
return return
} }
} }
}
// Fall back to Basic auth if provided // Fall back to Basic auth if provided
if username, ok := attemptBasicAuth(r, guiCfg, ldapCfg, evLogger); ok { if username, ok := attemptBasicAuth(r, guiCfg, ldapCfg, evLogger); ok {
@ -198,21 +203,26 @@ func createSession(cookieName string, username string, guiCfg config.GUIConfigur
func handleLogout(cookieName string) http.Handler { func handleLogout(cookieName string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie(cookieName) for _, cookie := range r.Cookies() {
if err == nil && cookie != nil { // 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() sessionsMut.Lock()
delete(sessions, cookie.Value) delete(sessions, cookie.Value)
sessionsMut.Unlock() sessionsMut.Unlock()
}
// else: If there is no session cookie, that's also a successful logout in terms of user experience.
// Delete the cookie
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: cookieName, Name: cookieName,
Value: "", Value: "",
MaxAge: -1, MaxAge: -1,
Secure: true, Secure: cookie.Secure,
Path: "/", Path: cookie.Path,
}) })
}
}
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
}) })
} }