跳转到内容

CSRF

Cross-Site Request Forgery(CSRF,有时读作 “sea-surf”,也称 XSRF)是一类恶意利用, 攻击者会从网站信任的用户那里传递未授权命令。

所有核心中间件都位于 middleware 包中:

import "github.com/labstack/echo/v5/middleware"
e.Use(middleware.CSRF())

CSRF 中间件支持 Sec-Fetch-Site header,作为现代的纵深防御方式来进行 CSRF protection, 它在传统 token 机制之外实现了 OWASP 推荐的 Fetch Metadata API。

现代浏览器会自动随每个请求发送 Sec-Fetch-Site header,表明请求来源和目标之间的关系。 中间件会用它做出安全决策:

  • same-origin 或 none:允许(完全同源或用户直接导航)
  • same-site:回退到 token 验证(例如子域到主域)
  • cross-site:对不安全方法(POST、PUT、DELETE、PATCH)默认以 403 错误阻止

对于不发送此 header 的浏览器(旧浏览器),中间件会无缝回退到传统基于 token 的 CSRF 防护。

两个选项可调整 Sec-Fetch-Site 行为:

  • TrustedOrigins []string:为跨站请求允许特定 origin(适用于 OAuth 回调、webhook)
  • AllowSecFetchSiteFunc func(c *echo.Context) (bool, error):用于 same-site/cross-site 验证的自定义逻辑
e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// Allow OAuth callbacks from a trusted provider.
TrustedOrigins: []string{"https://oauth-provider.com"},
// Custom validation for same-site/cross-site requests.
AllowSecFetchSiteFunc: func(c *echo.Context) (bool, error) {
// Your custom authorization logic here.
return validateCustomAuth(c), nil
// return true, err // blocks the request with an error
// return true, nil // allows the request through
// return false, nil // falls back to legacy token logic
},
}))
e := echo.New()
e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
TokenLookup: "header:X-XSRF-TOKEN",
}))

上面的示例会从 X-XSRF-TOKEN 请求 header 中提取 CSRF token。

改为从 Cookie 读取 token:

middleware.CSRFWithConfig(middleware.CSRFConfig{
TokenLookup: "cookie:_csrf",
CookiePath: "/",
CookieDomain: "example.com",
CookieSecure: true,
CookieHTTPOnly: true,
CookieSameSite: http.SameSiteStrictMode,
})
  • 服务端:token 可从上下文的 ContextKey 下取得,并可通过模板传给客户端。
  • 客户端:token 可从 CSRF Cookie 中读取。

CSRFConfig · github.com/labstack/echo/v5@5196b9b

字段说明由英文源码注释生成。

包源码中的字段
字段类型说明源码
SkipperSkipperSkipper defines a function to skip middleware.L29
TrustedOrigins[]stringTrustedOrigins permits any request with `Sec-Fetch-Site` header whose `Origin` header exactly matches a configured origin. Values should be formatted as Origin header "scheme://host[:port]". See [Origin]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin See [Sec-Fetch-Site]: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#fetch-metadata-headersL36
AllowSecFetchSiteFuncfunc(c *echo.Context) (bool, error)AllowSecFetchSiteFunc allows custom behaviour for `Sec-Fetch-Site` requests that are about to fail with CSRF error, to be allowed or replaced with custom error. This function applies to `Sec-Fetch-Site` values: - `same-site` same registrable domain (subdomain and/or different port) - `cross-site` request originates from different site See [Sec-Fetch-Site]: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#fetch-metadata-headersL44
TokenLengthuint8TokenLength is the length of the generated token.L47
TokenLookupstringTokenLookup is a string in the form of "<source>:<name>" or "<source>:<name>,<source>:<name>" that is used to extract token from the request. Optional. Default value "header:X-CSRF-Token". Possible values: - "header:<name>" or "header:<name>:<cut-prefix>" - "query:<name>" - "form:<name>" Multiple sources example: - "header:X-CSRF-Token,query:csrf"L59
Generatorfunc() stringGenerator defines a function to generate token. Optional. Defaults to randomString(TokenLength).L63
ContextKeystringContext key to store generated CSRF token into context. Optional. Default value "csrf".L67
CookieNamestringName of the CSRF cookie. This cookie will store CSRF token. Optional. Default value "csrf".L71
CookieDomainstringDomain of the CSRF cookie. Optional. Default value none.L75
CookiePathstringPath of the CSRF cookie. Optional. Default value none.L79
CookieMaxAgeintMax age (in seconds) of the CSRF cookie. Optional. Default value 86400 (24hr).L83
CookieSecureboolIndicates if CSRF cookie is secure. Optional. Default value false.L87
CookieHTTPOnlyboolIndicates if CSRF cookie is HTTP only. Optional. Default value false.L91
CookieSameSitehttp.SameSiteIndicates SameSite mode of the CSRF cookie. Optional. Default value SameSiteDefaultMode.L95
ErrorHandlerfunc(c *echo.Context, err error) errorErrorHandler defines a function which is executed for returning custom errors.L98
包源码中的函数
类型源码
func CSRF() echo.MiddlewareFuncL117
func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFuncL122
var DefaultCSRFConfig = CSRFConfig{
Skipper: DefaultSkipper,
TokenLength: 32,
TokenLookup: "header:" + echo.HeaderXCSRFToken,
ContextKey: "csrf",
CookieName: "_csrf",
CookieMaxAge: 86400,
CookieSameSite: http.SameSiteDefaultMode,
}

完整、可运行的示例可在 echox cookbook 中找到。