fix: broken STS Sessions with large policies (#1096)

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2021-10-04 14:25:00 -07:00
committed by GitHub
parent 7a864d2631
commit 1b225e0901
7 changed files with 109 additions and 30 deletions

View File

@@ -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)
})
})

View File

@@ -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)
})
})

View File

@@ -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 {