Add SameSite setting for cookies (#14900)

Add SameSite setting for cookies and rationalise the cookie setting code. Switches SameSite to Lax by default. 

There is a possible future extension of differentiating which cookies could be set at Strict by default but that is for a future PR.

Fix #5583

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
zeripath 2021-03-07 08:12:43 +00:00 committed by GitHub
parent beed5476e2
commit 9b261f52f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 184 additions and 45 deletions

View file

@ -386,9 +386,28 @@ func (ctx *Context) Redirect(location string, status ...int) {
http.Redirect(ctx.Resp, ctx.Req, location, code)
}
// SetCookie set cookies to web browser
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
middleware.SetCookie(ctx.Resp, name, value, others...)
// SetCookie convenience function to set most cookies consistently
// CSRF and a few others are the exception here
func (ctx *Context) SetCookie(name, value string, expiry int) {
middleware.SetCookie(ctx.Resp, name, value,
expiry,
setting.AppSubURL,
setting.SessionConfig.Domain,
setting.SessionConfig.Secure,
true,
middleware.SameSite(setting.SessionConfig.SameSite))
}
// DeleteCookie convenience function to delete most cookies consistently
// CSRF and a few others are the exception here
func (ctx *Context) DeleteCookie(name string) {
middleware.SetCookie(ctx.Resp, name, "",
-1,
setting.AppSubURL,
setting.SessionConfig.Domain,
setting.SessionConfig.Secure,
true,
middleware.SameSite(setting.SessionConfig.SameSite))
}
// GetCookie returns given cookie value from request header.
@ -399,6 +418,11 @@ func (ctx *Context) GetCookie(name string) string {
// GetSuperSecureCookie returns given cookie value from request header with secret string.
func (ctx *Context) GetSuperSecureCookie(secret, name string) (string, bool) {
val := ctx.GetCookie(name)
return ctx.CookieDecrypt(secret, val)
}
// CookieDecrypt returns given value from with secret string.
func (ctx *Context) CookieDecrypt(secret, val string) (string, bool) {
if val == "" {
return "", false
}
@ -414,14 +438,21 @@ func (ctx *Context) GetSuperSecureCookie(secret, name string) (string, bool) {
}
// SetSuperSecureCookie sets given cookie value to response header with secret string.
func (ctx *Context) SetSuperSecureCookie(secret, name, value string, others ...interface{}) {
func (ctx *Context) SetSuperSecureCookie(secret, name, value string, expiry int) {
text := ctx.CookieEncrypt(secret, value)
ctx.SetCookie(name, text, expiry)
}
// CookieEncrypt encrypts a given value using the provided secret
func (ctx *Context) CookieEncrypt(secret, value string) string {
key := pbkdf2.Key([]byte(secret), []byte(secret), 1000, 16, sha256.New)
text, err := com.AESGCMEncrypt(key, []byte(value))
if err != nil {
panic("error encrypting cookie: " + err.Error())
}
ctx.SetCookie(name, hex.EncodeToString(text), others...)
return hex.EncodeToString(text)
}
// GetCookieInt returns cookie result in int type.
@ -533,6 +564,7 @@ func getCsrfOpts() CsrfOptions {
Header: "X-Csrf-Token",
CookieDomain: setting.SessionConfig.Domain,
CookiePath: setting.SessionConfig.CookiePath,
SameSite: setting.SessionConfig.SameSite,
}
}
@ -597,17 +629,17 @@ func Contexter() func(next http.Handler) http.Handler {
middleware.Domain(setting.SessionConfig.Domain),
middleware.HTTPOnly(true),
middleware.Secure(setting.SessionConfig.Secure),
//middlewares.SameSite(opt.SameSite), FIXME: we need a samesite config
middleware.SameSite(setting.SessionConfig.SameSite),
)
return
}
ctx.SetCookie("macaron_flash", "", -1,
middleware.SetCookie(ctx.Resp, "macaron_flash", "", -1,
setting.SessionConfig.CookiePath,
middleware.Domain(setting.SessionConfig.Domain),
middleware.HTTPOnly(true),
middleware.Secure(setting.SessionConfig.Secure),
//middleware.SameSite(), FIXME: we need a samesite config
middleware.SameSite(setting.SessionConfig.SameSite),
)
})