github.com/labstack/echo/v4
Advanced tools
@@ -89,3 +89,3 @@ // SPDX-License-Identifier: MIT | ||
| { | ||
| name: "ok, token from POST header, second token passes", | ||
| name: "nok, token from POST header, tokens limited to 1, second token would pass", | ||
| whenTokenLookup: "header:" + echo.HeaderXCSRFToken, | ||
@@ -126,3 +126,3 @@ givenCSRFCookie: "token", | ||
| { | ||
| name: "ok, token from PUT query form, second token passes", | ||
| name: "nok, token from PUT query form, second token would pass", | ||
| whenTokenLookup: "query:csrf", | ||
@@ -240,2 +240,3 @@ givenCSRFCookie: "token", | ||
| expectCookieContains string | ||
| expectTokenInContext string | ||
| expectErr string | ||
@@ -247,2 +248,3 @@ }{ | ||
| expectCookieContains: "_csrf", | ||
| expectTokenInContext: "TESTTOKEN", | ||
| }, | ||
@@ -257,2 +259,3 @@ { | ||
| expectCookieContains: "_csrf", | ||
| expectTokenInContext: token, | ||
| }, | ||
@@ -286,2 +289,3 @@ { | ||
| expectCookieContains: "_csrf", | ||
| expectTokenInContext: "TESTTOKEN", | ||
| }, | ||
@@ -293,5 +297,14 @@ { | ||
| }, | ||
| whenMethod: http.MethodPost, | ||
| whenMethod: http.MethodPost, | ||
| expectTokenInContext: "_echo_csrf_using_sec_fetch_site_", | ||
| }, | ||
| { | ||
| name: "ok, safe method + SecFetchSite=same-origin passes", | ||
| whenHeaders: map[string]string{ | ||
| echo.HeaderSecFetchSite: "same-origin", | ||
| }, | ||
| whenMethod: http.MethodGet, | ||
| expectTokenInContext: "_echo_csrf_using_sec_fetch_site_", | ||
| }, | ||
| { | ||
| name: "nok, unsafe method + SecFetchSite=same-cross blocked", | ||
@@ -322,2 +335,7 @@ whenHeaders: map[string]string{ | ||
| } | ||
| if config.generator == nil { | ||
| config.generator = func(_ uint8) string { | ||
| return "TESTTOKEN" | ||
| } | ||
| } | ||
| mw, err := config.ToMiddleware() | ||
@@ -331,2 +349,4 @@ if tc.expectMWError != "" { | ||
| h := mw(func(c echo.Context) error { | ||
| cToken := c.Get(cmp.Or(config.ContextKey, DefaultCSRFConfig.ContextKey)) | ||
| assert.Equal(t, tc.expectTokenInContext, cToken) | ||
| return c.String(http.StatusOK, "test") | ||
@@ -571,3 +591,2 @@ }) | ||
| expectAllow: false, | ||
| expectErr: ``, | ||
| }, | ||
@@ -630,3 +649,2 @@ { | ||
| expectAllow: false, | ||
| expectErr: ``, | ||
| }, | ||
@@ -647,3 +665,2 @@ { | ||
| expectAllow: false, | ||
| expectErr: ``, | ||
| }, | ||
@@ -650,0 +667,0 @@ { |
+21
-1
@@ -16,2 +16,11 @@ // SPDX-License-Identifier: MIT | ||
| // CSRFUsingSecFetchSite is a context key for CSRF middleware what is set when the client browser is using Sec-Fetch-Site | ||
| // header and the request is deemed safe. | ||
| // It is a dummy token value that can be used to render CSRF token for form by handlers. | ||
| // | ||
| // We know that the client is using a browser that supports Sec-Fetch-Site header, so when the form is submitted in | ||
| // the future with this dummy token value it is OK. Although the request is safe, the template rendered by the | ||
| // handler may need this value to render CSRF token for form. | ||
| const CSRFUsingSecFetchSite = "_echo_csrf_using_sec_fetch_site_" | ||
| // CSRFConfig defines the config for CSRF middleware. | ||
@@ -87,2 +96,4 @@ type CSRFConfig struct { | ||
| ErrorHandler CSRFErrorHandler | ||
| generator func(length uint8) string | ||
| } | ||
@@ -150,2 +161,6 @@ | ||
| } | ||
| tokenGenerator := randomString | ||
| if config.generator != nil { | ||
| tokenGenerator = config.generator | ||
| } | ||
@@ -176,3 +191,3 @@ extractors, cErr := CreateExtractors(config.TokenLookup) | ||
| if k, err := c.Cookie(config.CookieName); err != nil { | ||
| token = randomString(config.TokenLength) | ||
| token = tokenGenerator(config.TokenLength) | ||
| } else { | ||
@@ -294,2 +309,7 @@ token = k.Value // Reuse token | ||
| if isSafe { | ||
| // This helps handlers that support older token-based CSRF protection. | ||
| // We know that the client is using a browser that supports Sec-Fetch-Site header, so when the form is submitted in | ||
| // the future with this dummy token value it is OK. Although the request is safe, the template rendered by the | ||
| // handler may need this value to render CSRF token for form. | ||
| c.Set(config.ContextKey, CSRFUsingSecFetchSite) | ||
| return true, nil | ||
@@ -296,0 +316,0 @@ } |