fix: broken STS Sessions with large policies (#1096)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
@@ -39,8 +39,10 @@ func registerAccountHandlers(api *operations.ConsoleAPI) {
|
||||
}
|
||||
// Custom response writer to update the session cookies
|
||||
return middleware.ResponderFunc(func(w http.ResponseWriter, p runtime.Producer) {
|
||||
cookie := NewSessionCookieForConsole(changePasswordResponse.SessionID)
|
||||
http.SetCookie(w, &cookie)
|
||||
cookies := NewSessionCookieForConsole(changePasswordResponse.SessionID)
|
||||
for _, cookie := range cookies {
|
||||
http.SetCookie(w, &cookie)
|
||||
}
|
||||
user_api.NewLoginCreated().WithPayload(changePasswordResponse).WriteResponse(w, p)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -53,8 +53,10 @@ func registerLoginHandlers(api *operations.ConsoleAPI) {
|
||||
}
|
||||
// Custom response writer to set the session cookies
|
||||
return middleware.ResponderFunc(func(w http.ResponseWriter, p runtime.Producer) {
|
||||
cookie := NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
http.SetCookie(w, &cookie)
|
||||
cookies := NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
for _, cookie := range cookies {
|
||||
http.SetCookie(w, &cookie)
|
||||
}
|
||||
user_api.NewLoginCreated().WithPayload(loginResponse).WriteResponse(w, p)
|
||||
})
|
||||
})
|
||||
@@ -65,8 +67,10 @@ func registerLoginHandlers(api *operations.ConsoleAPI) {
|
||||
}
|
||||
// Custom response writer to set the session cookies
|
||||
return middleware.ResponderFunc(func(w http.ResponseWriter, p runtime.Producer) {
|
||||
cookie := NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
http.SetCookie(w, &cookie)
|
||||
cookies := NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
for _, cookie := range cookies {
|
||||
http.SetCookie(w, &cookie)
|
||||
}
|
||||
user_api.NewLoginOauth2AuthCreated().WithPayload(loginResponse).WriteResponse(w, p)
|
||||
})
|
||||
})
|
||||
@@ -77,8 +81,10 @@ func registerLoginHandlers(api *operations.ConsoleAPI) {
|
||||
}
|
||||
// Custom response writer to set the session cookies
|
||||
return middleware.ResponderFunc(func(w http.ResponseWriter, p runtime.Producer) {
|
||||
cookie := NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
http.SetCookie(w, &cookie)
|
||||
cookies := NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
for _, cookie := range cookies {
|
||||
http.SetCookie(w, &cookie)
|
||||
}
|
||||
user_api.NewLoginOperatorCreated().WithPayload(loginResponse).WriteResponse(w, p)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -18,6 +18,7 @@ package restapi
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -105,22 +106,73 @@ func FileExists(filename string) bool {
|
||||
return !info.IsDir()
|
||||
}
|
||||
|
||||
func NewSessionCookieForConsole(token string) http.Cookie {
|
||||
expiration := time.Now().Add(SessionDuration)
|
||||
func NewSessionCookieForConsole(token string) []http.Cookie {
|
||||
const CookieChunk = 3800
|
||||
|
||||
return http.Cookie{
|
||||
Path: "/",
|
||||
Name: "token",
|
||||
Value: token,
|
||||
MaxAge: int(SessionDuration.Seconds()), // 45 minutes
|
||||
Expires: expiration,
|
||||
HttpOnly: true,
|
||||
// if len(GlobalPublicCerts) > 0 is true, that means Console is running with TLS enable and the browser
|
||||
// should not leak any cookie if we access the site using HTTP
|
||||
Secure: len(GlobalPublicCerts) > 0,
|
||||
// read more: https://web.dev/samesite-cookies-explained/
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
expiration := time.Now().Add(SessionDuration)
|
||||
var cookies []http.Cookie
|
||||
|
||||
i := 0
|
||||
cookieIndex := 0
|
||||
|
||||
for i < len(token) {
|
||||
var until int
|
||||
if i+CookieChunk < len(token) {
|
||||
until = i + CookieChunk
|
||||
} else {
|
||||
until = len(token)
|
||||
}
|
||||
|
||||
cookieName := "token"
|
||||
if len(cookies) > 0 {
|
||||
cookieName = fmt.Sprintf("token%d", len(cookies))
|
||||
}
|
||||
|
||||
cookie := http.Cookie{
|
||||
Path: "/",
|
||||
Name: cookieName,
|
||||
Value: token[i:until],
|
||||
MaxAge: int(SessionDuration.Seconds()), // 45 minutes
|
||||
Expires: expiration,
|
||||
HttpOnly: true,
|
||||
// if len(GlobalPublicCerts) > 0 is true, that means Console is running with TLS enable and the browser
|
||||
// should not leak any cookie if we access the site using HTTP
|
||||
Secure: len(GlobalPublicCerts) > 0,
|
||||
// read more: https://web.dev/samesite-cookies-explained/
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
}
|
||||
|
||||
cookies = append(cookies, cookie)
|
||||
i += until
|
||||
cookieIndex++
|
||||
}
|
||||
|
||||
// clear old cookies
|
||||
expiredDuration := time.Now().Add(-1 * time.Second)
|
||||
for i := cookieIndex; i < 10; i++ {
|
||||
cookieName := "token"
|
||||
if len(cookies) > 0 {
|
||||
cookieName = fmt.Sprintf("token%d", i)
|
||||
}
|
||||
|
||||
cookie := http.Cookie{
|
||||
Path: "/",
|
||||
Name: cookieName,
|
||||
Value: "",
|
||||
MaxAge: 0, // 45 minutes
|
||||
Expires: expiredDuration,
|
||||
HttpOnly: true,
|
||||
// if len(GlobalPublicCerts) > 0 is true, that means Console is running with TLS enable and the browser
|
||||
// should not leak any cookie if we access the site using HTTP
|
||||
Secure: len(GlobalPublicCerts) > 0,
|
||||
// read more: https://web.dev/samesite-cookies-explained/
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
}
|
||||
|
||||
cookies = append(cookies, cookie)
|
||||
}
|
||||
|
||||
return cookies
|
||||
}
|
||||
|
||||
func ExpireSessionCookie() http.Cookie {
|
||||
|
||||
Reference in New Issue
Block a user