Documentation
¶
Overview ¶
Package csrf provides lightweight CSRF protection for Go net/http servers using the double-submit cookie pattern.
How it works
- Safe methods (GET, HEAD, OPTIONS): ensure a CSRF token cookie exists and inject the token into the request context so handlers can read it via TokenFromContext.
- Unsafe methods (POST, PUT, PATCH, DELETE): optionally enforce same-site policy using Origin/Referer (when EnforceOriginCheck is enabled) and then require the client-provided token (from header or form field) to match the token stored in the cookie. Comparison is done in constant time.
Configuration ¶
All behavior is driven by Config. Key fields include:
- CookieName, CookiePath, CookieDomain, CookieSecure, CookieHTTPOnly, CookieSameSite, CookieMaxAge
- HeaderName (default: "X-CSRF-Token")
- FormField (default: "csrf_token")
- EnforceOriginCheck and AllowedOrigin (empty means use the request host)
- TokenBytes (default: 32)
HttpOnly note By default many double-submit implementations keep HttpOnly=false so client code can read the token when necessary. If you do not need client-side reads (e.g., you fetch tokens via TokenHandler or inject them server-side), set CookieHTTPOnly=true.
Typical usage
p := csrf.New(csrf.Config{ EnforceOriginCheck: true })
// Protect an http.Handler (router, mux, etc.)
protected := p.Protect(appMux)
http.ListenAndServe(":8080", protected)
In handlers, you can read the token from context for rendering or APIs:
if tok, ok := csrf.TokenFromContext(r.Context()); ok {
// use tok in templates or return it from an endpoint
}
For SPAs, expose a small endpoint that returns the current token:
r.Get("/csrf-token", func(w http.ResponseWriter, r *http.Request) {
p.TokenHandler().ServeHTTP(w, r)
})
Repository <https://github.com/JeanGrijp/go-csrf>
README and Examples
- README: <https://github.com/JeanGrijp/go-csrf#readme>
- chi: <https://github.com/JeanGrijp/go-csrf/blob/main/examples/chi/main.go>
- gin: <https://github.com/JeanGrijp/go-csrf/blob/main/examples/gin/main.go>
Go Reference <https://pkg.go.dev/github.com/JeanGrijp/go-csrf/csrf>
Package csrf provides a lightweight double-submit-cookie CSRF protection middleware.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func TokenFromContext ¶
TokenFromContext returns the CSRF token stored in ctx, if present.
Params: - ctx: context potentially containing a token set by the middleware.
Returns: - token (string) and a boolean indicating whether a token was found.
Types ¶
type Config ¶
type Config struct {
// CookieName is the name of the CSRF token cookie.
// Default: "csrf_token".
CookieName string
// CookiePath is the Path attribute for the CSRF cookie.
// Default: "/".
CookiePath string
// CookieDomain is the Domain attribute for the CSRF cookie.
// Leave empty to omit the attribute.
CookieDomain string
// CookieSecure controls the Secure flag of the CSRF cookie.
// Should be true in production when using HTTPS.
CookieSecure bool
// CookieHTTPOnly controls the HttpOnly flag of the CSRF cookie.
// Default: false (double-submit pattern commonly requires client-side read).
// Set to true if you always fetch the token via TokenHandler or inject it server-side.
CookieHTTPOnly bool
// CookieSameSite sets the SameSite attribute of the CSRF cookie.
// Default: http.SameSiteLaxMode.
CookieSameSite http.SameSite
// CookieMaxAge is the Max-Age attribute in seconds.
// 0 means a session cookie (no Max-Age attribute). Negative values are not set by this package.
CookieMaxAge int // in seconds
// HeaderName is the HTTP header from which the client provides the token
// on unsafe requests.
// Default: "X-CSRF-Token".
HeaderName string
// FormField is the form field name (application/x-www-form-urlencoded or
// multipart/form-data) from which the client may provide the token.
// Default: "csrf_token".
FormField string
// EnforceOriginCheck, when true, validates that unsafe requests originate
// from the same site by checking the Origin header or, if absent, the
// Referer header.
EnforceOriginCheck bool
// AllowedOrigin is the allowed site (host) for same-site checks when
// EnforceOriginCheck is enabled. If empty, the current request host (r.Host)
// is used.
// Example: "app.example.com"
AllowedOrigin string
// TokenBytes is the number of random bytes used to generate the token
// before base64url encoding (no padding).
// Default: 32.
TokenBytes int
}
Config holds cookie attributes, token transport options and security flags used by the CSRF protector. New applies sensible defaults when fields are left empty/zero.
Notes
- This middleware uses the double-submit cookie pattern, which requires the CSRF cookie to be readable by client-side code; therefore the cookie is set with HttpOnly=false by design.
- Defaults applied by New when zero values are provided: CookieName="csrf_token", CookiePath="/", CookieSameSite=http.SameSiteLaxMode, HeaderName="X-CSRF-Token", FormField="csrf_token", TokenBytes=32.
type Protector ¶
type Protector struct {
// contains filtered or unexported fields
}
func New ¶
New receives a Config (cfg) with cookie, transport and security settings, applies reasonable defaults when fields are empty, and returns a configured *Protector ready to be used as middleware. It never returns nil.
Params: - cfg: configuration values (cookie options, header/form names, security flags).
Returns: - *Protector with defaults applied.
func (*Protector) Protect ¶
Protect wraps the given next http.Handler and enforces CSRF protection.
Behavior:
- For "safe" methods (GET/HEAD/OPTIONS): ensures the token cookie exists and injects the token into the request context, then calls next.
- For "unsafe" methods (POST/PUT/PATCH/DELETE): optionally validates Origin/Referer (when EnforceOriginCheck is true), extracts the client token from header or form, compares it in constant time against the cookie token, and only then calls next.
Params: - next: downstream handler to be executed after CSRF checks pass.
Returns: - An http.Handler that performs the CSRF logic before delegating to next.
func (*Protector) TokenHandler ¶
TokenHandler returns an HTTP handler that writes the current CSRF token. This is useful for SPAs to fetch the token and attach it to subsequent requests.
Returns: - http.Handler that responds with the token in the response body (text/plain).