CSRF Plugin
The CSRF plugin provides server-side protection against Cross-Site Request Forgery attacks using the Double-Submit Cookie pattern integrated into Authula's lifecycle hook system.
Core Functionality
Token Generation
On safe HTTP methods (GET, HEAD, OPTIONS), the plugin automatically generates a cryptographically secure token and sets it as a cookie. The cookie is intentionally readable by JavaScript to enable the Double-Submit pattern.
Token Validation
On state-changing methods (POST, PUT, PATCH, DELETE), the plugin validates that the CSRF token exists in both a cookie and a request header, and that both values match exactly. Requests with missing or mismatched tokens are rejected with a 403 response.
Token Cleanup
When users sign out, the plugin automatically clears the CSRF cookie.
Integration Architecture
The plugin integrates with Authula through the lifecycle hook system, registering handlers at specific stages:
- Before Hook (Order 5): Token generation for safe methods
- Before Hook (Order 15): Token validation for unsafe methods (requires explicit opt-in via route metadata)
- After Hook (Order 15): Cookie cleanup on sign-out
Routes must explicitly request CSRF protection by including the plugin identifier in their metadata. This allows selective protection—authentication endpoints like sign-in can skip validation while authenticated endpoints enforce it.
Optional Layered Protection
Beyond the Double-Submit pattern, the plugin optionally supports header-based origin validation using Go 1.25's CrossOriginProtection. When enabled, this validates Sec-Fetch-Site, Origin, and Host headers against configured trusted origins before token validation occurs.
Standalone Mode
Configure the CSRF plugin in your TOML configuration file:
[plugins.csrf]
enabled = true
cookie_name = "authula_csrf_token"
header_name = "X-AUTHULA-CSRF-TOKEN"
max_age = "24h"
secure = true
same_site = "lax"
enable_header_protection = falseConfiguration Options
| Option | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable or disable the plugin |
cookie_name | string | "authula_csrf_token" | Name of the CSRF cookie |
header_name | string | "X-AUTHULA-CSRF-TOKEN" | Name of the CSRF header |
max_age | duration | "24h" | Token lifetime before expiration |
secure | boolean | false | Force Secure flag on cookies |
same_site | string | "lax" | SameSite attribute: lax, strict, or none |
enable_header_protection | boolean | false | Enable Go's CrossOriginProtection |
Library Mode
To use the plugin programmatically, instantiate it as part of the plugins array when creating a new Authula instance:
csrfplugin.New(csrfplugin.CSRFPluginConfig{
Enabled: true,
CookieName: "authula_csrf_token",
HeaderName: "X-AUTHULA-CSRF-TOKEN",
MaxAge: time.Hour * 24,
Secure: false,
SameSite: "lax",
EnableHeaderProtection: false,
})Key Design Decisions
- HttpOnly=false: Required for Double-Submit pattern where JavaScript must read the cookie value
- Selective enforcement: Only validates on routes that explicitly request protection
- Defense in depth: Optional header protection provides additional layer beyond tokens
- Hot reloadable: Configuration changes apply without server restart
