Pular para o conteúdo

CSRF

Cross-Site Request Forgery (CSRF, às vezes pronunciado “sea-surf”, ou XSRF) é um tipo de exploit malicioso em que comandos não autorizados são transmitidos a partir de um usuário em que um site confia.

Todo o middleware principal fica no pacote middleware:

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

O middleware CSRF oferece suporte ao header Sec-Fetch-Site como uma abordagem moderna de defense-in-depth para proteção CSRF, implementando a Fetch Metadata API recomendada pela OWASP junto do mecanismo tradicional baseado em token.

Navegadores modernos enviam automaticamente o header Sec-Fetch-Site com cada request, indicando a relação entre a origem do request e o destino. O middleware usa isso para tomar uma decisão de segurança:

  • same-origin ou none — permitido (correspondência exata de origem ou navegação direta do usuário)
  • same-site — recorre à validação de token (por exemplo, subdomínio para domínio principal)
  • cross-site — bloqueado por padrão com um erro 403 para métodos inseguros (POST, PUT, DELETE, PATCH)

Para navegadores que não enviam este header (navegadores mais antigos), o middleware recorre automaticamente à proteção CSRF tradicional baseada em token.

Duas opções ajustam o comportamento de Sec-Fetch-Site:

  • TrustedOrigins []string — allowlist de origens específicas para requests cross-site (útil para callbacks OAuth, webhooks)
  • AllowSecFetchSiteFunc func(c *echo.Context) (bool, error) — lógica customizada para validação 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",
}))

O exemplo acima extrai o token CSRF do header de request X-XSRF-TOKEN.

Lendo o token de um cookie:

middleware.CSRFWithConfig(middleware.CSRFConfig{
TokenLookup: "cookie:_csrf",
CookiePath: "/",
CookieDomain: "example.com",
CookieSecure: true,
CookieHTTPOnly: true,
CookieSameSite: http.SameSiteStrictMode,
})
  • Server-side — o token fica disponível no contexto sob ContextKey e pode ser passado ao cliente via template.
  • Client-side — o token pode ser lido do cookie CSRF.

CSRFConfig · github.com/labstack/echo/[email protected]

As descrições dos campos são geradas dos comentários do código-fonte em inglês.

Campos do código-fonte
CampoTipoDescriçãoCódigo
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
Funções do código-fonte
TipoCódigo
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,
}

Um exemplo completo e executável está disponível no echox cookbook.