fix: broken STS Sessions with large policies (#1096)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
@@ -55,8 +55,10 @@ func registerLoginHandlers(api *operations.OperatorAPI) {
|
||||
}
|
||||
// Custom response writer to set the session cookies
|
||||
return middleware.ResponderFunc(func(w http.ResponseWriter, p runtime.Producer) {
|
||||
cookie := restapi.NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
http.SetCookie(w, &cookie)
|
||||
cookies := restapi.NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
for _, cookie := range cookies {
|
||||
http.SetCookie(w, &cookie)
|
||||
}
|
||||
user_api.NewLoginCreated().WithPayload(loginResponse).WriteResponse(w, p)
|
||||
})
|
||||
})
|
||||
@@ -67,8 +69,10 @@ func registerLoginHandlers(api *operations.OperatorAPI) {
|
||||
}
|
||||
// Custom response writer to set the session cookies
|
||||
return middleware.ResponderFunc(func(w http.ResponseWriter, p runtime.Producer) {
|
||||
cookie := restapi.NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
http.SetCookie(w, &cookie)
|
||||
cookies := restapi.NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
for _, cookie := range cookies {
|
||||
http.SetCookie(w, &cookie)
|
||||
}
|
||||
user_api.NewLoginOauth2AuthCreated().WithPayload(loginResponse).WriteResponse(w, p)
|
||||
})
|
||||
})
|
||||
@@ -79,8 +83,10 @@ func registerLoginHandlers(api *operations.OperatorAPI) {
|
||||
}
|
||||
// Custom response writer to set the session cookies
|
||||
return middleware.ResponderFunc(func(w http.ResponseWriter, p runtime.Producer) {
|
||||
cookie := restapi.NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
http.SetCookie(w, &cookie)
|
||||
cookies := restapi.NewSessionCookieForConsole(loginResponse.SessionID)
|
||||
for _, cookie := range cookies {
|
||||
http.SetCookie(w, &cookie)
|
||||
}
|
||||
user_api.NewLoginOperatorCreated().WithPayload(loginResponse).WriteResponse(w, p)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -287,6 +287,7 @@ func decrypt(ciphertext []byte, associatedData []byte) ([]byte, error) {
|
||||
func GetTokenFromRequest(r *http.Request) (string, error) {
|
||||
// Token might come either as a Cookie or as a Header
|
||||
// if not set in cookie, check if it is set on Header.
|
||||
|
||||
tokenCookie, err := r.Cookie("token")
|
||||
if err != nil {
|
||||
return "", ErrNoAuthToken
|
||||
@@ -295,7 +296,16 @@ func GetTokenFromRequest(r *http.Request) (string, error) {
|
||||
if tokenCookie.Expires.After(currentTime) {
|
||||
return "", errTokenExpired
|
||||
}
|
||||
return strings.TrimSpace(tokenCookie.Value), nil
|
||||
|
||||
mergeToken := strings.TrimSpace(tokenCookie.Value)
|
||||
for _, cookie := range r.Cookies() {
|
||||
if cookie.Name != "token" && strings.HasPrefix(cookie.Name, "token") {
|
||||
mergeToken = fmt.Sprintf("%s%s", mergeToken, strings.TrimSpace(cookie.Value))
|
||||
}
|
||||
}
|
||||
|
||||
return mergeToken, nil
|
||||
|
||||
}
|
||||
|
||||
func GetClaimsFromTokenInRequest(req *http.Request) (*models.Principal, error) {
|
||||
|
||||
@@ -76,6 +76,9 @@ export const deleteCookie = (name: string) => {
|
||||
export const clearSession = () => {
|
||||
storage.removeItem("token");
|
||||
deleteCookie("token");
|
||||
for (let i = 1; i < 10; i++) {
|
||||
deleteCookie(`token${i}`);
|
||||
}
|
||||
};
|
||||
|
||||
// timeFromDate gets time string from date input
|
||||
|
||||
@@ -136,7 +136,7 @@ const ModalWrapper = ({
|
||||
return;
|
||||
}
|
||||
// Open SnackBar
|
||||
if(modalSnackMessage.type !== "error") {
|
||||
if (modalSnackMessage.type !== "error") {
|
||||
setOpenSnackbar(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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