The CSRF middleware protects against Cross-Site Request Forgery attacks by validating tokens on unsafe HTTP methods such as POST, PUT, and DELETE. It responds with 403 Forbidden when validation fails.
Production Requirements:
CookieSecure: true (HTTPS only)
CookieSameSite: "Lax" or "Strict"
- Use
Session store for better security
Signatures
func New(config ...Config) fiber.Handler
func TokenFromContext(ctx any) string
func HandlerFromContext(ctx any) *Handler
TokenFromContext and HandlerFromContext accept a fiber.CustomCtx, fiber.Ctx, a *fasthttp.RequestCtx, or a context.Context.
Usage
import (
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/extractors"
"github.com/gofiber/fiber/v3/middleware/csrf"
)
Development Configuration
// Default config (development only)
app.Use(csrf.New())
Production Configuration
app.Use(csrf.New(csrf.Config{
CookieName: "__Host-csrf_",
CookieSecure: true,
CookieHTTPOnly: true, // false for SPAs
CookieSameSite: "Lax",
CookieSessionOnly: true,
Extractor: extractors.FromHeader("X-Csrf-Token"),
Session: sessionStore,
}))
Server-Side Rendered Apps
app.Use(csrf.New(csrf.Config{
CookieName: "__Host-csrf_",
CookieSecure: true,
CookieHTTPOnly: true, // Secure - blocks JavaScript
CookieSameSite: "Lax",
CookieSessionOnly: true,
Extractor: extractors.FromForm("_csrf"),
Session: sessionStore,
}))
Single Page Applications (SPAs)
app.Use(csrf.New(csrf.Config{
CookieName: "__Host-csrf_",
CookieSecure: true,
CookieHTTPOnly: false, // Required for JavaScript access
CookieSameSite: "Lax",
CookieSessionOnly: true,
Extractor: extractors.FromHeader("X-Csrf-Token"),
Session: sessionStore,
}))
Using CSRF Tokens
func formHandler(c fiber.Ctx) error {
token := csrf.TokenFromContext(c)
return c.SendString(fmt.Sprintf(`
<form method="POST" action="/submit">
<input type="hidden" name="_csrf" value="%s">
<input type="text" name="message" required>
<button type="submit">Submit</button>
</form>
`, token))
}
Single Page Applications
func apiHandler(c fiber.Ctx) error {
token := csrf.TokenFromContext(c)
return c.JSON(fiber.Map{
"csrf_token": token,
"data": "your data",
})
}
// Get CSRF token from cookie
function getCsrfToken() {
const value = `; ${document.cookie}`;
const parts = value.split(`; __Host-csrf_=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
// Use with fetch API
async function makeRequest(url, data) {
const csrfToken = getCsrfToken();
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Csrf-Token': csrfToken
},
body: JSON.stringify(data)
});
return response.json();
}
Configuration
Next
func(fiber.Ctx) bool
default:"nil"
Skip middleware when returns true.
HTTPS only cookie (required for production).
Prevent JavaScript access (use false for SPAs).
SameSite attribute (use “Lax” or “Strict”).
Session-only cookie (expires on browser close).
IdleTimeout
time.Duration
default:"30 * time.Minute"
Token expiration time.
KeyGenerator
func() string
default:"utils.SecureToken"
Token generation function.
ErrorHandler
fiber.ErrorHandler
default:"defaultErrorHandler"
Custom error handler.
Token extraction method with metadata.
Disables redaction of tokens and storage keys in logs and error messages.
Session
*session.Store
default:"nil"
Session store (recommended for production).
Storage
fiber.Storage
default:"nil"
Token storage (overridden by Session).
Trusted origins for cross-origin requests.
Generate new token after each use.
Security Model
The middleware employs a defense-in-depth strategy:
Token Validation Patterns
Double Submit Cookie (Default Mode): Used when a Session store is not configured. The server stores tokens but doesn’t tie them to specific users.
Synchronizer Token (Session-Based Mode): Automatically enabled when you provide a Session store. Tokens are tied to user sessions for stronger protection.
// Enable Synchronizer Token pattern
app.Use(csrf.New(csrf.Config{
Session: sessionStore, // Activates session-based mode
}))
Origin & Referer Validation
The middleware always performs Origin and Referer header checks for unsafe requests (when the connection is HTTPS). The request’s origin must match the application’s Host header or be explicitly allowed in the TrustedOrigins list.
Advanced Configuration
Trusted Origins
app.Use(csrf.New(csrf.Config{
TrustedOrigins: []string{
"https://trusted.example.com",
"https://*.example.com", // Wildcard subdomains
},
}))
Custom Error Handler
app.Use(csrf.New(csrf.Config{
ErrorHandler: func(c fiber.Ctx, err error) error {
accepts := c.Accepts("html", "json")
if accepts == "json" {
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
"error": "Forbidden",
})
}
return c.Status(fiber.StatusForbidden).Render("error", fiber.Map{
"Title": "Forbidden",
})
},
}))
Token Management
// Delete token (e.g., on logout)
handler := csrf.HandlerFromContext(c)
if handler != nil {
if err := handler.DeleteToken(c); err != nil {
// handle error
}
}
Common Use Cases
app.Use(csrf.New(csrf.Config{
Extractor: extractors.FromForm("_csrf"),
}))
API with Multiple Client Types
// Support both AJAX and form submissions
app.Use(csrf.New(csrf.Config{
Extractor: extractors.Chain(
extractors.FromHeader("X-Csrf-Token"),
extractors.FromForm("_csrf"),
),
}))
Route-Specific Configuration
// API routes - header extraction
api := app.Group("/api")
api.Use(csrf.New(csrf.Config{
Extractor: extractors.FromHeader("X-Csrf-Token"),
}))
// Form routes - form field extraction
forms := app.Group("/forms")
forms.Use(csrf.New(csrf.Config{
Extractor: extractors.FromForm("_csrf"),
}))