The web/csrf package provides two CSRF strategies: the session-backed synchronizer token (default) and the double-submit cookie.

Import

How it works

The middleware decision tree — storage (synchronizer vs. double-submit) only changes where the token is loaded from, not this validation path: CSRF protection validates every request whose method is not in Config.SafeMethods. The default safe methods are GET, HEAD, and OPTIONSTRACE is intentionally not safe: it can echo request contents and is disabled on hardened servers, so the safer default is to treat it as state-changing (a token is required). On a safe-method request, the middleware ensures a token exists (generating and persisting one if absent) and exposes it via csrf.TokenFrom(ctx) for handlers/templates to render. On an unsafe-method request, it loads the expected token, reads the actual token from the configured header then the form param, and compares them with a constant-time check.

Synchronizer Token (default)

The token is stored as a session attribute (not a cookie) and is stable across requests until Rotate is called.
NewSynchronizerRepository(store session.Store, cookie session.CookieConfig) csrf.Repository takes the same session.Store and session.CookieConfig used by the session middleware, so it can locate the caller’s session. There is no XSRF-TOKEN cookie written by this strategy — the token never leaves the session, so a client that needs to read the token (e.g. an SPA) must get it from a page render via csrf.TokenFrom, not from a cookie. Stateless alternative — no session required. The token is stored in a cookie and mirrored in the X-CSRF-Token header; the server compares the cookie value to the echoed header/form value.
NewDoubleSubmitRepository(cookie session.CookieConfig) csrf.Repository writes the CSRF cookie with HttpOnly: false (so client JavaScript can read and echo it) but keeps Secure and SameSite=Lax. This is the only cookie in the web layer permitted to be non-HttpOnly. The double-submit cookie is not HMAC-signed — it relies on the same-origin policy preventing another origin from reading or setting the cookie, not on a secret. It is weaker than the synchronizer against subdomain / cookie-injection attacks (an attacker who can set a cookie on a sibling subdomain can forge both halves), so prefer the synchronizer whenever a session exists.

SPA integration

Angular, React, and Vue all support reading a cookie and sending it as a header — this only applies to the double-submit strategy, since the synchronizer strategy never puts the token in a cookie. The Token.HeaderName this library expects defaults to X-CSRF-Token (there is no constructor parameter to change it), so point your SPA’s client at that header name rather than assuming a framework’s own default:

Disabling CSRF

CSRF can only be disabled for bearer-token-authenticated APIs where session cookies are never used:
Combining CSRFDisabled() with WithLogin() is a login-CSRF vulnerability. New() errors on this pair unless you call AllowLoginWithoutCSRF() to confirm that CSRF is enforced at another layer (e.g. an edge gateway).

Custom exemptions

To exempt specific paths from CSRF (e.g. a webhook endpoint), set Config.Skip, a predicate over the request. securityhttp does not currently expose Skip, so build the middleware directly with csrf.Middleware when you need exemptions: