Documentation
¶
Overview ¶
Package csrf implements a signed, browser-session-bound, origin-aware double-submit CSRF defense for fh.
Security properties:
- HMAC-SHA256 signed CSRF tokens with signing-key rotation.
- Tokens are bound to an HttpOnly browser-binding cookie and may also be bound to an application/authentication session via SessionBinding.
- Exact scheme + host + effective-port Origin/Referer validation.
- Fetch Metadata validation (Sec-Fetch-Site) as defense in depth.
- Strict Origin validation for WebSocket handshakes.
- Secure, SameSite=Lax, __Host- cookies by default.
- Constant-time comparison of submitted and cookie tokens.
- Header and HTML form token extraction; custom extraction is supported.
For horizontally scaled production deployments, configure Secret or Keys so every instance shares the same signing material. If neither is configured, a cryptographically random process-local key is used; that is secure for a single process but tokens will not survive restarts or work across replicas.
Index ¶
- Variables
- func New(config ...Config) fh.HandlerFunc
- func NewWithError(config ...Config) (fh.HandlerFunc, error)
- func RotateToken(c fh.Ctx, config ...Config) (string, error)
- func Token(c fh.Ctx, config ...Config) string
- type Config
- type Key
- type Protector
- type SessionBinding
- type TargetOriginResolver
- type TokenExtractor
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidConfig = errors.New("csrf: invalid configuration") ErrInvalidToken = errors.New("csrf: invalid token") )
var DefaultConfig = defaultConfig()
DefaultConfig is a compatibility snapshot of the defaults.
Deprecated: New does not read this mutable variable; mutating it does not alter middleware defaults. This prevents global mutation/races from silently weakening security. Construct Config values explicitly instead.
Functions ¶
func New ¶
func New(config ...Config) fh.HandlerFunc
New returns CSRF middleware and preserves the historical fh middleware API. Invalid configuration panics at application startup rather than silently running with weakened protection. Use NewWithError when explicit error handling is preferred.
func NewWithError ¶
func NewWithError(config ...Config) (fh.HandlerFunc, error)
NewWithError validates config and returns a middleware handler.
func RotateToken ¶
RotateToken preserves the historical package-level API. For repeated use, prefer constructing a Protector once and calling protector.RotateToken(c).
Types ¶
type Config ¶
type Config struct {
CookieName string
HeaderName string
FormField string
CookiePath string
CookieDomain string
CookieSecure bool
// AllowInsecureCookie is required to disable Secure on CSRF cookies. This
// explicit opt-out prevents a partial Config literal from silently weakening
// the secure default. Intended for loopback/local development only.
AllowInsecureCookie bool
CookieSameSite fh.SameSite
// CookieMaxAge controls both CSRF cookies. Zero creates session cookies.
// A session cookie is the default so CSRF lifetime does not accidentally
// outlive or conflict with an application's authentication lifetime.
CookieMaxAge time.Duration
// BindingCookieName names the HttpOnly random browser-session binding cookie.
// It is included in the CSRF-token MAC and prevents cookie-injection/fixation
// attacks against a naive double-submit construction.
BindingCookieName string
// DisableBrowserBinding explicitly disables the HttpOnly browser-binding
// cookie. This weakens the default and should normally be used only when a
// strong SessionBinding is always available.
DisableBrowserBinding bool
// Secret is a convenient single active key. For key rotation, prefer Keys.
// If both Secret and Keys are configured, configuration is rejected.
Secret []byte
// Keys enables signing-key rotation. The first key signs; every key verifies.
Keys []Key
// SessionBinding optionally binds tokens to the application's auth/session
// identity in addition to the default browser-session binding cookie.
SessionBinding SessionBinding
// TrustedOrigins are exact additional origins allowed to submit unsafe
// requests, e.g. "https://app.example.com". Wildcards are intentionally not
// supported.
TrustedOrigins []string
// TargetOrigin pins the browser-visible target origin. It is strongly
// recommended behind TLS-terminating reverse proxies/load balancers.
TargetOrigin string
// TargetOriginResolver is the dynamic equivalent of TargetOrigin. Configure
// at most one of TargetOrigin and TargetOriginResolver.
TargetOriginResolver TargetOriginResolver
// RequireOriginHeader is retained for source compatibility. The secure
// default is true. Because bool zero-values cannot express an explicit false
// in a partial Config, use AllowMissingOrigin to opt out.
RequireOriginHeader bool
// AllowMissingOrigin permits unsafe requests carrying neither Origin nor
// Referer. Prefer bypassing CSRF on authenticated non-browser routes instead.
AllowMissingOrigin bool
// AllowUntrustedOrigin disables Origin/Referer and Fetch Metadata enforcement
// while retaining token verification. Intended only for local development.
AllowUntrustedOrigin bool
// CheckFetchMetadata is retained as an enable switch. It is enabled by
// default. Use DisableFetchMetadata for an explicit opt-out.
CheckFetchMetadata bool
// DisableFetchMetadata explicitly disables Sec-Fetch-Site validation.
DisableFetchMetadata bool
// ProtectWebSockets enables strict Origin/Fetch-Metadata checks for WebSocket
// handshakes even though HTTP GET is normally a safe method. Enabled by
// default. Browser WebSocket APIs cannot reliably attach the CSRF header, so
// WebSocket protection is origin-based rather than token-header-based.
ProtectWebSockets bool
// AllowUnprotectedWebSockets explicitly disables the secure WebSocket default.
AllowUnprotectedWebSockets bool
// AutoRotateOnChange automatically re-issues the CSRF token when the
// session binding changes (for example after login, logout, or account
// switching). When true, the middleware detects binding changes by
// comparing a short HMAC fingerprint stored in a companion cookie and
// calls RotateToken transparently. This closes the gap where a
// pre-authentication CSRF token could remain valid after the session
// identity changes.
AutoRotateOnChange bool
// Extractor overrides HeaderName/FormField extraction when non-nil.
Extractor TokenExtractor
// Next bypasses this middleware for selected routes. Prefer this for
// authenticated machine-to-machine/non-browser APIs instead of weakening
// global origin policy.
Next func(fh.Ctx) bool
}
Config controls CSRF protection.
type Key ¶
Key is an HMAC signing key. The first configured key signs newly-issued tokens. All configured keys verify existing tokens, allowing safe rotation.
ID is embedded in the token and must consist only of ASCII letters, digits, '-' or '_'. Secret must be at least 32 bytes.
type Protector ¶
type Protector struct {
// contains filtered or unexported fields
}
Protector is an immutable, validated CSRF configuration. It can be reused by middleware and explicit token-rotation calls.
func NewProtector ¶
NewProtector constructs an immutable Protector for middleware and explicit rotation/clearing operations.
func (*Protector) Clear ¶
Clear expires both CSRF cookies using the configured path/domain/security attributes. It is useful on logout/account switching.
func (*Protector) Middleware ¶
Middleware enforces CSRF protection.
type SessionBinding ¶
SessionBinding returns stable, non-secret bytes identifying the current application/authentication session. When configured, CSRF tokens become invalid automatically when that binding changes (for example after login, logout, account switching, or session-ID regeneration).
Do not return a password, access token, or other credential. A random internal session ID is ideal. The binding is used only as HMAC input and is never sent to the client by this package.
type TargetOriginResolver ¶
TargetOriginResolver returns the externally-visible target origin for the current request, such as "https://example.com". Use this behind a trusted reverse proxy when c.BaseURL() reflects the internal hop rather than the browser-visible scheme/host. The returned value must contain only an origin: scheme + host + optional port, with no path/query/fragment/userinfo.
Do not blindly copy Forwarded/X-Forwarded-* headers in this callback unless a trusted-proxy middleware has already validated and sanitized them.
type TokenExtractor ¶
TokenExtractor overrides the default request-token extraction logic. It is useful for custom body formats. Tokens should never be accepted from URL query parameters because URLs commonly leak into logs, browser history and Referer.