mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-03 21:08:25 +00: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:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user