Ir al contenido

CSRF

Cross-Site Request Forgery (CSRF, a veces pronunciado “sea-surf”, o XSRF) es un tipo de exploit malicioso en el que se transmiten comandos no autorizados desde un usuario en el que un sitio web confía.

Todo el middleware principal reside en el paquete middleware:

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

El middleware CSRF soporta el header Sec-Fetch-Site como un enfoque moderno de defensa en profundidad para la protección CSRF, implementando la Fetch Metadata API recomendada por OWASP junto al mecanismo tradicional basado en tokens.

Los navegadores modernos envían automáticamente el header Sec-Fetch-Site con cada request, indicando la relación entre el origin del request y el destino. El middleware usa esto para tomar una decisión de seguridad:

  • same-origin o none: permitido (coincidencia exacta de origin o navegación directa del usuario)
  • same-site: vuelve a la validación por token (por ejemplo, de subdominio a dominio principal)
  • cross-site: bloqueado por defecto con un error 403 para métodos inseguros (POST, PUT, DELETE, PATCH)

Para navegadores que no envían este header (navegadores más antiguos), el middleware vuelve sin interrupciones a la protección CSRF tradicional basada en tokens.

Dos opciones ajustan el comportamiento de Sec-Fetch-Site:

  • TrustedOrigins []string: allowlist de origins específicos para requests cross-site (útil para callbacks OAuth, webhooks)
  • AllowSecFetchSiteFunc func(c *echo.Context) (bool, error): lógica personalizada para validación 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",
}))

El ejemplo anterior extrae el token CSRF del header de request X-XSRF-TOKEN.

Leer el token desde una cookie en su lugar:

middleware.CSRFWithConfig(middleware.CSRFConfig{
TokenLookup: "cookie:_csrf",
CookiePath: "/",
CookieDomain: "example.com",
CookieSecure: true,
CookieHTTPOnly: true,
CookieSameSite: http.SameSiteStrictMode,
})
  • Server-side: el token está disponible desde el contexto bajo ContextKey y se puede pasar al cliente mediante un template.
  • Client-side: el token se puede leer desde la cookie CSRF.

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

Las descripciones de los campos se generan a partir de comentarios del código fuente en inglés.

Campos del código fuente
CampoTipoDescripciónFuente
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
Funciones del código fuente
TipoFuente
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,
}

Hay un ejemplo completo y ejecutable disponible en el recetario de echox.