mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	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:
		| @@ -794,6 +794,8 @@ COOKIE_SECURE = false | ||||
| GC_INTERVAL_TIME = 86400 | ||||
| ; Session life time in seconds, default is 86400 (1 day) | ||||
| SESSION_LIFE_TIME = 86400 | ||||
| ; SameSite settings. Either "none", "lax", or "strict" | ||||
| SAME_SITE=lax | ||||
|  | ||||
| [picture] | ||||
| AVATAR_UPLOAD_PATH = data/avatars | ||||
|   | ||||
| @@ -557,6 +557,8 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type | ||||
| - `COOKIE_NAME`: **i\_like\_gitea**: The name of the cookie used for the session ID. | ||||
| - `GC_INTERVAL_TIME`: **86400**: GC interval in seconds. | ||||
| - `SESSION_LIFE_TIME`: **86400**: Session life time in seconds, default is 86400 (1 day) | ||||
| - `DOMAIN`: **\<empty\>**: Sets the cookie Domain | ||||
| - `SAME_SITE`: **lax** \[strict, lax, none\]: Set the SameSite setting for the cookie. | ||||
|  | ||||
| ## Picture (`picture`) | ||||
|  | ||||
|   | ||||
| @@ -13,7 +13,6 @@ import ( | ||||
|  | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
| ) | ||||
|  | ||||
| @@ -129,8 +128,8 @@ func handleSignIn(resp http.ResponseWriter, req *http.Request, sess SessionStore | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	middleware.SetCookie(resp, "lang", user.Language, nil, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 	middleware.SetLocaleCookie(resp, user.Language, 0) | ||||
|  | ||||
| 	// Clear whatever CSRF has right now, force to generate a new one | ||||
| 	middleware.SetCookie(resp, setting.CSRFCookieName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 	middleware.DeleteCSRFCookie(resp) | ||||
| } | ||||
|   | ||||
| @@ -9,6 +9,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/models" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
| ) | ||||
|  | ||||
| // ToggleOptions contains required or check options | ||||
| @@ -41,7 +42,7 @@ func Toggle(options *ToggleOptions) func(ctx *Context) { | ||||
| 					ctx.Data["Title"] = ctx.Tr("auth.must_change_password") | ||||
| 					ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password" | ||||
| 					if ctx.Req.URL.Path != "/user/events" { | ||||
| 						ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) | ||||
| 						middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI()) | ||||
| 					} | ||||
| 					ctx.Redirect(setting.AppSubURL + "/user/settings/change_password") | ||||
| 					return | ||||
| @@ -69,7 +70,7 @@ func Toggle(options *ToggleOptions) func(ctx *Context) { | ||||
| 		if options.SignInRequired { | ||||
| 			if !ctx.IsSigned { | ||||
| 				if ctx.Req.URL.Path != "/user/events" { | ||||
| 					ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) | ||||
| 					middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI()) | ||||
| 				} | ||||
| 				ctx.Redirect(setting.AppSubURL + "/user/login") | ||||
| 				return | ||||
| @@ -84,7 +85,7 @@ func Toggle(options *ToggleOptions) func(ctx *Context) { | ||||
| 		if !options.SignOutRequired && !ctx.IsSigned && | ||||
| 			len(ctx.GetCookie(setting.CookieUserName)) > 0 { | ||||
| 			if ctx.Req.URL.Path != "/user/events" { | ||||
| 				ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) | ||||
| 				middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI()) | ||||
| 			} | ||||
| 			ctx.Redirect(setting.AppSubURL + "/user/login") | ||||
| 			return | ||||
|   | ||||
| @@ -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), | ||||
| 				) | ||||
| 			}) | ||||
|  | ||||
|   | ||||
| @@ -22,6 +22,8 @@ import ( | ||||
| 	"net/http" | ||||
| 	"time" | ||||
|  | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
|  | ||||
| 	"github.com/unknwon/com" | ||||
| ) | ||||
|  | ||||
| @@ -37,6 +39,8 @@ type CSRF interface { | ||||
| 	GetCookiePath() string | ||||
| 	// Return the flag value used for the csrf token. | ||||
| 	GetCookieHTTPOnly() bool | ||||
| 	// Return cookie domain | ||||
| 	GetCookieDomain() string | ||||
| 	// Return the token. | ||||
| 	GetToken() string | ||||
| 	// Validate by token. | ||||
| @@ -93,6 +97,11 @@ func (c *csrf) GetCookieHTTPOnly() bool { | ||||
| 	return c.CookieHTTPOnly | ||||
| } | ||||
|  | ||||
| // GetCookieDomain returns the flag value used for the csrf token. | ||||
| func (c *csrf) GetCookieDomain() string { | ||||
| 	return c.CookieDomain | ||||
| } | ||||
|  | ||||
| // GetToken returns the current token. This is typically used | ||||
| // to populate a hidden form in an HTML template. | ||||
| func (c *csrf) GetToken() string { | ||||
| @@ -227,10 +236,14 @@ func Csrfer(opt CsrfOptions, ctx *Context) CSRF { | ||||
| 			if opt.CookieLifeTime == 0 { | ||||
| 				expires = time.Now().AddDate(0, 0, 1) | ||||
| 			} | ||||
| 			ctx.SetCookie(opt.Cookie, x.Token, opt.CookieLifeTime, opt.CookiePath, opt.CookieDomain, opt.Secure, opt.CookieHTTPOnly, expires, | ||||
| 				func(c *http.Cookie) { | ||||
| 					c.SameSite = opt.SameSite | ||||
| 				}, | ||||
| 			middleware.SetCookie(ctx.Resp, opt.Cookie, x.Token, | ||||
| 				opt.CookieLifeTime, | ||||
| 				opt.CookiePath, | ||||
| 				opt.CookieDomain, | ||||
| 				opt.Secure, | ||||
| 				opt.CookieHTTPOnly, | ||||
| 				expires, | ||||
| 				middleware.SameSite(opt.SameSite), | ||||
| 			) | ||||
| 		} | ||||
| 	} | ||||
| @@ -248,14 +261,22 @@ func Csrfer(opt CsrfOptions, ctx *Context) CSRF { | ||||
| func Validate(ctx *Context, x CSRF) { | ||||
| 	if token := ctx.Req.Header.Get(x.GetHeaderName()); len(token) > 0 { | ||||
| 		if !x.ValidToken(token) { | ||||
| 			ctx.SetCookie(x.GetCookieName(), "", -1, x.GetCookiePath()) | ||||
| 			// Delete the cookie | ||||
| 			middleware.SetCookie(ctx.Resp, x.GetCookieName(), "", | ||||
| 				-1, | ||||
| 				x.GetCookiePath(), | ||||
| 				x.GetCookieDomain()) // FIXME: Do we need to set the Secure, httpOnly and SameSite values too? | ||||
| 			x.Error(ctx.Resp) | ||||
| 		} | ||||
| 		return | ||||
| 	} | ||||
| 	if token := ctx.Req.FormValue(x.GetFormName()); len(token) > 0 { | ||||
| 		if !x.ValidToken(token) { | ||||
| 			ctx.SetCookie(x.GetCookieName(), "", -1, x.GetCookiePath()) | ||||
| 			// Delete the cookie | ||||
| 			middleware.SetCookie(ctx.Resp, x.GetCookieName(), "", | ||||
| 				-1, | ||||
| 				x.GetCookiePath(), | ||||
| 				x.GetCookieDomain()) // FIXME: Do we need to set the Secure, httpOnly and SameSite values too? | ||||
| 			x.Error(ctx.Resp) | ||||
| 		} | ||||
| 		return | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| package setting | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| @@ -31,10 +32,13 @@ var ( | ||||
| 		Secure bool | ||||
| 		// Cookie domain name. Default is empty. | ||||
| 		Domain string | ||||
| 		// SameSite declares if your cookie should be restricted to a first-party or same-site context. Valid strings are "none", "lax", "strict". Default is "lax" | ||||
| 		SameSite http.SameSite | ||||
| 	}{ | ||||
| 		CookieName:  "i_like_gitea", | ||||
| 		Gclifetime:  86400, | ||||
| 		Maxlifetime: 86400, | ||||
| 		SameSite:    http.SameSiteLaxMode, | ||||
| 	} | ||||
| ) | ||||
|  | ||||
| @@ -52,6 +56,15 @@ func newSessionService() { | ||||
| 	SessionConfig.Gclifetime = sec.Key("GC_INTERVAL_TIME").MustInt64(86400) | ||||
| 	SessionConfig.Maxlifetime = sec.Key("SESSION_LIFE_TIME").MustInt64(86400) | ||||
| 	SessionConfig.Domain = sec.Key("DOMAIN").String() | ||||
| 	samesiteString := sec.Key("SAME_SITE").In("lax", []string{"none", "lax", "strict"}) | ||||
| 	switch strings.ToLower(samesiteString) { | ||||
| 	case "none": | ||||
| 		SessionConfig.SameSite = http.SameSiteNoneMode | ||||
| 	case "strict": | ||||
| 		SessionConfig.SameSite = http.SameSiteStrictMode | ||||
| 	default: | ||||
| 		SessionConfig.SameSite = http.SameSiteLaxMode | ||||
| 	} | ||||
|  | ||||
| 	json := jsoniter.ConfigCompatibleWithStandardLibrary | ||||
| 	shadowConfig, err := json.Marshal(SessionConfig) | ||||
|   | ||||
| @@ -76,6 +76,47 @@ func NewCookie(name, value string, maxAge int) *http.Cookie { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // SetRedirectToCookie convenience function to set the RedirectTo cookie consistently | ||||
| func SetRedirectToCookie(resp http.ResponseWriter, value string) { | ||||
| 	SetCookie(resp, "redirect_to", value, | ||||
| 		0, | ||||
| 		setting.AppSubURL, | ||||
| 		"", | ||||
| 		setting.SessionConfig.Secure, | ||||
| 		true, | ||||
| 		SameSite(setting.SessionConfig.SameSite)) | ||||
| } | ||||
|  | ||||
| // DeleteRedirectToCookie convenience function to delete most cookies consistently | ||||
| func DeleteRedirectToCookie(resp http.ResponseWriter) { | ||||
| 	SetCookie(resp, "redirect_to", "", | ||||
| 		-1, | ||||
| 		setting.AppSubURL, | ||||
| 		"", | ||||
| 		setting.SessionConfig.Secure, | ||||
| 		true, | ||||
| 		SameSite(setting.SessionConfig.SameSite)) | ||||
| } | ||||
|  | ||||
| // DeleteSesionConfigPathCookie convenience function to delete SessionConfigPath cookies consistently | ||||
| func DeleteSesionConfigPathCookie(resp http.ResponseWriter, name string) { | ||||
| 	SetCookie(resp, name, "", | ||||
| 		-1, | ||||
| 		setting.SessionConfig.CookiePath, | ||||
| 		setting.SessionConfig.Domain, | ||||
| 		setting.SessionConfig.Secure, | ||||
| 		true, | ||||
| 		SameSite(setting.SessionConfig.SameSite)) | ||||
| } | ||||
|  | ||||
| // DeleteCSRFCookie convenience function to delete SessionConfigPath cookies consistently | ||||
| func DeleteCSRFCookie(resp http.ResponseWriter) { | ||||
| 	SetCookie(resp, setting.CSRFCookieName, "", | ||||
| 		-1, | ||||
| 		setting.SessionConfig.CookiePath, | ||||
| 		setting.SessionConfig.Domain) // FIXME: Do we need to set the Secure, httpOnly and SameSite values too? | ||||
| } | ||||
|  | ||||
| // SetCookie set the cookies | ||||
| // TODO: Copied from gitea.com/macaron/macaron and should be improved after macaron removed. | ||||
| func SetCookie(resp http.ResponseWriter, name string, value string, others ...interface{}) { | ||||
|   | ||||
| @@ -7,6 +7,7 @@ package middleware | ||||
| import ( | ||||
| 	"net/http" | ||||
|  | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/translation" | ||||
|  | ||||
| 	"github.com/unknwon/i18n" | ||||
| @@ -42,8 +43,30 @@ func Locale(resp http.ResponseWriter, req *http.Request) translation.Locale { | ||||
| 	} | ||||
|  | ||||
| 	if changeLang { | ||||
| 		SetCookie(resp, "lang", lang, 1<<31-1) | ||||
| 		SetLocaleCookie(resp, lang, 1<<31-1) | ||||
| 	} | ||||
|  | ||||
| 	return translation.NewLocale(lang) | ||||
| } | ||||
|  | ||||
| // SetLocaleCookie convenience function to set the locale cookie consistently | ||||
| func SetLocaleCookie(resp http.ResponseWriter, lang string, expiry int) { | ||||
| 	SetCookie(resp, "lang", lang, expiry, | ||||
| 		setting.AppSubURL, | ||||
| 		setting.SessionConfig.Domain, | ||||
| 		setting.SessionConfig.Secure, | ||||
| 		true, | ||||
| 		SameSite(setting.SessionConfig.SameSite)) | ||||
| } | ||||
|  | ||||
| // DeleteLocaleCookie convenience function to delete the locale cookie consistently | ||||
| // Setting the lang cookie will trigger the middleware to reset the language ot previous state. | ||||
| func DeleteLocaleCookie(resp http.ResponseWriter) { | ||||
| 	SetCookie(resp, "lang", "", | ||||
| 		-1, | ||||
| 		setting.AppSubURL, | ||||
| 		setting.SessionConfig.Domain, | ||||
| 		setting.SessionConfig.Secure, | ||||
| 		true, | ||||
| 		SameSite(setting.SessionConfig.SameSite)) | ||||
| } | ||||
|   | ||||
| @@ -17,6 +17,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/structs" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
| 	"code.gitea.io/gitea/routers/user" | ||||
| ) | ||||
|  | ||||
| @@ -46,7 +47,7 @@ func Home(ctx *context.Context) { | ||||
| 		} else if ctx.User.MustChangePassword { | ||||
| 			ctx.Data["Title"] = ctx.Tr("auth.must_change_password") | ||||
| 			ctx.Data["ChangePasscodeLink"] = setting.AppSubURL + "/user/change_password" | ||||
| 			ctx.SetCookie("redirect_to", setting.AppSubURL+ctx.Req.URL.RequestURI(), 0, setting.AppSubURL) | ||||
| 			middleware.SetRedirectToCookie(ctx.Resp, setting.AppSubURL+ctx.Req.URL.RequestURI()) | ||||
| 			ctx.Redirect(setting.AppSubURL + "/user/settings/change_password") | ||||
| 		} else { | ||||
| 			user.Dashboard(ctx) | ||||
|   | ||||
| @@ -424,9 +424,10 @@ func InstallPost(ctx *context.Context) { | ||||
| 		} | ||||
|  | ||||
| 		days := 86400 * setting.LogInRememberDays | ||||
| 		ctx.SetCookie(setting.CookieUserName, u.Name, days, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 		ctx.SetCookie(setting.CookieUserName, u.Name, days) | ||||
|  | ||||
| 		ctx.SetSuperSecureCookie(base.EncodeMD5(u.Rands+u.Passwd), | ||||
| 			setting.CookieRememberName, u.Name, days, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 			setting.CookieRememberName, u.Name, days) | ||||
|  | ||||
| 		// Auto-login for admin | ||||
| 		if err = ctx.Session.Set("uid", u.ID); err != nil { | ||||
|   | ||||
| @@ -24,6 +24,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
| 	"code.gitea.io/gitea/routers/utils" | ||||
| 	"code.gitea.io/gitea/services/externalaccount" | ||||
| 	"code.gitea.io/gitea/services/mailer" | ||||
| @@ -64,8 +65,8 @@ func AutoSignIn(ctx *context.Context) (bool, error) { | ||||
| 	defer func() { | ||||
| 		if !isSucceed { | ||||
| 			log.Trace("auto-login cookie cleared: %s", uname) | ||||
| 			ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 			ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 			ctx.DeleteCookie(setting.CookieUserName) | ||||
| 			ctx.DeleteCookie(setting.CookieRememberName) | ||||
| 		} | ||||
| 	}() | ||||
|  | ||||
| @@ -95,7 +96,7 @@ func AutoSignIn(ctx *context.Context) (bool, error) { | ||||
| 		return false, err | ||||
| 	} | ||||
|  | ||||
| 	ctx.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 	middleware.DeleteCSRFCookie(ctx.Resp) | ||||
| 	return true, nil | ||||
| } | ||||
|  | ||||
| @@ -109,13 +110,13 @@ func checkAutoLogin(ctx *context.Context) bool { | ||||
|  | ||||
| 	redirectTo := ctx.Query("redirect_to") | ||||
| 	if len(redirectTo) > 0 { | ||||
| 		ctx.SetCookie("redirect_to", redirectTo, 0, setting.AppSubURL, "", setting.SessionConfig.Secure, true) | ||||
| 		middleware.SetRedirectToCookie(ctx.Resp, redirectTo) | ||||
| 	} else { | ||||
| 		redirectTo = ctx.GetCookie("redirect_to") | ||||
| 	} | ||||
|  | ||||
| 	if isSucceed { | ||||
| 		ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL, "", setting.SessionConfig.Secure, true) | ||||
| 		middleware.DeleteRedirectToCookie(ctx.Resp) | ||||
| 		ctx.RedirectToFirst(redirectTo, setting.AppSubURL+string(setting.LandingPageURL)) | ||||
| 		return true | ||||
| 	} | ||||
| @@ -497,9 +498,9 @@ func handleSignIn(ctx *context.Context, u *models.User, remember bool) { | ||||
| func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyRedirect bool) string { | ||||
| 	if remember { | ||||
| 		days := 86400 * setting.LogInRememberDays | ||||
| 		ctx.SetCookie(setting.CookieUserName, u.Name, days, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 		ctx.SetCookie(setting.CookieUserName, u.Name, days) | ||||
| 		ctx.SetSuperSecureCookie(base.EncodeMD5(u.Rands+u.Passwd), | ||||
| 			setting.CookieRememberName, u.Name, days, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 			setting.CookieRememberName, u.Name, days) | ||||
| 	} | ||||
|  | ||||
| 	_ = ctx.Session.Delete("openid_verified_uri") | ||||
| @@ -530,10 +531,10 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	ctx.SetCookie("lang", u.Language, nil, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 	middleware.SetLocaleCookie(ctx.Resp, u.Language, 0) | ||||
|  | ||||
| 	// Clear whatever CSRF has right now, force to generate a new one | ||||
| 	ctx.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 	middleware.DeleteCSRFCookie(ctx.Resp) | ||||
|  | ||||
| 	// Register last login | ||||
| 	u.SetLastLogin() | ||||
| @@ -543,7 +544,7 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR | ||||
| 	} | ||||
|  | ||||
| 	if redirectTo := ctx.GetCookie("redirect_to"); len(redirectTo) > 0 && !utils.IsExternalURL(redirectTo) { | ||||
| 		ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL, "", setting.SessionConfig.Secure, true) | ||||
| 		middleware.DeleteRedirectToCookie(ctx.Resp) | ||||
| 		if obeyRedirect { | ||||
| 			ctx.RedirectToFirst(redirectTo) | ||||
| 		} | ||||
| @@ -649,7 +650,7 @@ func handleOAuth2SignIn(u *models.User, gothUser goth.User, ctx *context.Context | ||||
| 		} | ||||
|  | ||||
| 		// Clear whatever CSRF has right now, force to generate a new one | ||||
| 		ctx.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 		middleware.DeleteCSRFCookie(ctx.Resp) | ||||
|  | ||||
| 		// Register last login | ||||
| 		u.SetLastLogin() | ||||
| @@ -664,7 +665,7 @@ func handleOAuth2SignIn(u *models.User, gothUser goth.User, ctx *context.Context | ||||
| 		} | ||||
|  | ||||
| 		if redirectTo := ctx.GetCookie("redirect_to"); len(redirectTo) > 0 { | ||||
| 			ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL, "", setting.SessionConfig.Secure, true) | ||||
| 			middleware.DeleteRedirectToCookie(ctx.Resp) | ||||
| 			ctx.RedirectToFirst(redirectTo) | ||||
| 			return | ||||
| 		} | ||||
| @@ -1042,11 +1043,11 @@ func LinkAccountPostRegister(ctx *context.Context) { | ||||
| func HandleSignOut(ctx *context.Context) { | ||||
| 	_ = ctx.Session.Flush() | ||||
| 	_ = ctx.Session.Destroy(ctx.Resp, ctx.Req) | ||||
| 	ctx.SetCookie(setting.CookieUserName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 	ctx.SetCookie(setting.CookieRememberName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 	ctx.SetCookie(setting.CSRFCookieName, "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 	ctx.SetCookie("lang", "", -1, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) // Setting the lang cookie will trigger the middleware to reset the language ot previous state. | ||||
| 	ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL)                                                            // logout default should set redirect to to default | ||||
| 	ctx.DeleteCookie(setting.CookieUserName) | ||||
| 	ctx.DeleteCookie(setting.CookieRememberName) | ||||
| 	middleware.DeleteCSRFCookie(ctx.Resp) | ||||
| 	middleware.DeleteLocaleCookie(ctx.Resp) | ||||
| 	middleware.DeleteRedirectToCookie(ctx.Resp) | ||||
| } | ||||
|  | ||||
| // SignOut sign out from login status | ||||
| @@ -1623,7 +1624,7 @@ func MustChangePasswordPost(ctx *context.Context) { | ||||
| 	log.Trace("User updated password: %s", u.Name) | ||||
|  | ||||
| 	if redirectTo := ctx.GetCookie("redirect_to"); len(redirectTo) > 0 && !utils.IsExternalURL(redirectTo) { | ||||
| 		ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL) | ||||
| 		middleware.DeleteRedirectToCookie(ctx.Resp) | ||||
| 		ctx.RedirectToFirst(redirectTo) | ||||
| 		return | ||||
| 	} | ||||
|   | ||||
| @@ -20,6 +20,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
| 	"code.gitea.io/gitea/services/mailer" | ||||
| ) | ||||
|  | ||||
| @@ -47,13 +48,13 @@ func SignInOpenID(ctx *context.Context) { | ||||
|  | ||||
| 	redirectTo := ctx.Query("redirect_to") | ||||
| 	if len(redirectTo) > 0 { | ||||
| 		ctx.SetCookie("redirect_to", redirectTo, 0, setting.AppSubURL, "", setting.SessionConfig.Secure, true) | ||||
| 		middleware.SetRedirectToCookie(ctx.Resp, redirectTo) | ||||
| 	} else { | ||||
| 		redirectTo = ctx.GetCookie("redirect_to") | ||||
| 	} | ||||
|  | ||||
| 	if isSucceed { | ||||
| 		ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL, "", setting.SessionConfig.Secure, true) | ||||
| 		middleware.DeleteRedirectToCookie(ctx.Resp) | ||||
| 		ctx.RedirectToFirst(redirectTo) | ||||
| 		return | ||||
| 	} | ||||
|   | ||||
| @@ -21,6 +21,7 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
| 	"code.gitea.io/gitea/modules/web" | ||||
| 	"code.gitea.io/gitea/modules/web/middleware" | ||||
|  | ||||
| 	"github.com/unknwon/i18n" | ||||
| ) | ||||
| @@ -116,7 +117,7 @@ func ProfilePost(ctx *context.Context) { | ||||
| 	} | ||||
|  | ||||
| 	// Update the language to the one we just set | ||||
| 	ctx.SetCookie("lang", ctx.User.Language, nil, setting.AppSubURL, setting.SessionConfig.Domain, setting.SessionConfig.Secure, true) | ||||
| 	middleware.SetLocaleCookie(ctx.Resp, ctx.User.Language, 0) | ||||
|  | ||||
| 	log.Trace("User settings updated: %s", ctx.User.Name) | ||||
| 	ctx.Flash.Success(i18n.Tr(ctx.User.Language, "settings.update_profile_success")) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user