-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Fix #1523 by adding SameSite mode for CSRF settings #1524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
8b2c77b
cb15226
dc147d9
53b38de
0807357
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,6 +57,10 @@ type ( | |
// Indicates if CSRF cookie is HTTP only. | ||
// Optional. Default value false. | ||
CookieHTTPOnly bool `yaml:"cookie_http_only"` | ||
|
||
// Indicates SameSite mode of the CSRF cookie. | ||
// Optional. Default value SameSiteDefaultMode. | ||
CookieSameSite http.SameSite `yaml:"cookie_same_site"` | ||
} | ||
|
||
// csrfTokenExtractor defines a function that takes `echo.Context` and returns | ||
|
@@ -67,12 +71,13 @@ type ( | |
var ( | ||
// DefaultCSRFConfig is the default CSRF middleware config. | ||
DefaultCSRFConfig = CSRFConfig{ | ||
Skipper: DefaultSkipper, | ||
TokenLength: 32, | ||
TokenLookup: "header:" + echo.HeaderXCSRFToken, | ||
ContextKey: "csrf", | ||
CookieName: "_csrf", | ||
CookieMaxAge: 86400, | ||
Skipper: DefaultSkipper, | ||
TokenLength: 32, | ||
TokenLookup: "header:" + echo.HeaderXCSRFToken, | ||
ContextKey: "csrf", | ||
CookieName: "_csrf", | ||
CookieMaxAge: 86400, | ||
CookieSameSite: http.SameSiteDefaultMode, | ||
} | ||
) | ||
|
||
|
@@ -105,6 +110,9 @@ func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc { | |
if config.CookieMaxAge == 0 { | ||
config.CookieMaxAge = DefaultCSRFConfig.CookieMaxAge | ||
} | ||
if config.CookieSameSite == http.SameSiteNoneMode { | ||
config.CookieSecure = true | ||
} | ||
|
||
// Initialize | ||
parts := strings.Split(config.TokenLookup, ":") | ||
|
@@ -157,6 +165,9 @@ func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc { | |
if config.CookieDomain != "" { | ||
cookie.Domain = config.CookieDomain | ||
} | ||
if config.CookieSameSite != http.SameSiteDefaultMode { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The article on the issue say this:
So maybe it could be good to set cookie.Secure=true when SameSite=None There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @pafuent Maybe you can correct the testing strategy to take at least GO version 1.13 as a basis? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would mean this is a breaking change, as for vecho 4 we still consider Go v1.12 supported. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lammel Are you suggesting to declare local constants that will be analogous in GoLang? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that is what I meant. Go v1.12 will not have any changes in that regard anymore. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, there will be a conflict. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I'm missing something but maybe we can do something like this: package main
import (
"fmt"
)
type SameSite int
const (
SameSiteDefaultMode SameSite = iota + 1
SameSiteLaxMode
SameSiteStrictMode
)
const (
SameSiteNoneMode SameSite = SameSiteStrictMode + 1
)
func main() {
var ss SameSite
ss = SameSiteLaxMode
fmt.Println(ss)
ss = SameSiteNoneMode
fmt.Println(ss)
} The tricky part is how to write it in order to select our version of the constant or the Go 1.13. Something like this (please test it, I didn't had the time to do it) samesite.go // +build !go1.12
package middleware
import (
"net/http"
)
const (
SameSiteNoneMode http.SameSite = http.SameSiteNoneMode
) samesite_1_12.go // +build go1.12
package middleware
import (
"net/http"
)
const (
SameSiteNoneMode http.SameSite = 4
) |
||
cookie.SameSite = config.CookieSameSite | ||
} | ||
cookie.Expires = time.Now().Add(time.Duration(config.CookieMaxAge) * time.Second) | ||
cookie.Secure = config.CookieSecure | ||
cookie.HttpOnly = config.CookieHTTPOnly | ||
|
Uh oh!
There was an error while loading. Please reload this page.