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 },}))基于 token 的防护
Section titled “基于 token 的防护”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,})访问 CSRF token
Section titled “访问 CSRF token”- 服务端: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 |
var DefaultCSRFConfig = CSRFConfig{ Skipper: DefaultSkipper, TokenLength: 32, TokenLookup: "header:" + echo.HeaderXCSRFToken, ContextKey: "csrf", CookieName: "_csrf", CookieMaxAge: 86400, CookieSameSite: http.SameSiteDefaultMode,}完整、可运行的示例可在 echox cookbook 中找到。