跳转到内容

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

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

包源码中的字段
字段类型说明源码
Skipper Skipper Skipper defines a function to skip middleware. L29
TrustedOrigins []string TrustedOrigins 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-headers L36
AllowSecFetchSiteFunc func(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-headers L44
TokenLength uint8 TokenLength is the length of the generated token. L47
TokenLookup string TokenLookup 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
Generator func() string Generator defines a function to generate token. Optional. Defaults to randomString(TokenLength). L63
ContextKey string Context key to store generated CSRF token into context. Optional. Default value "csrf". L67
CookieName string Name of the CSRF cookie. This cookie will store CSRF token. Optional. Default value "csrf". L71
CookieDomain string Domain of the CSRF cookie. Optional. Default value none. L75
CookiePath string Path of the CSRF cookie. Optional. Default value none. L79
CookieMaxAge int Max age (in seconds) of the CSRF cookie. Optional. Default value 86400 (24hr). L83
CookieSecure bool Indicates if CSRF cookie is secure. Optional. Default value false. L87
CookieHTTPOnly bool Indicates if CSRF cookie is HTTP only. Optional. Default value false. L91
CookieSameSite http.SameSite Indicates SameSite mode of the CSRF cookie. Optional. Default value SameSiteDefaultMode. L95
ErrorHandler func(c *echo.Context, err error) error ErrorHandler defines a function which is executed for returning custom errors. L98
包源码中的函数
类型源码
func CSRF() echo.MiddlewareFunc L117
func CSRFWithConfig(config CSRFConfig) echo.MiddlewareFunc L122
var DefaultCSRFConfig = CSRFConfig{
Skipper: DefaultSkipper,
TokenLength: 32,
TokenLookup: "header:" + echo.HeaderXCSRFToken,
ContextKey: "csrf",
CookieName: "_csrf",
CookieMaxAge: 86400,
CookieSameSite: http.SameSiteDefaultMode,
}

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