Skip to content

CSRF

Cross-Site Request Forgery protection using gorilla/csrf.

Package: github.com/oliverandrich/burrow/contrib/csrf

Depends on: none

Setup

srv := burrow.NewServer(
    session.New(),
    csrf.New(),
    // ... other apps
)

The CSRF app provides middleware that protects POST/PUT/DELETE/PATCH requests using the double-submit cookie pattern. GET, HEAD, OPTIONS, and TRACE requests pass through without validation.

How It Works

  1. On every request, the middleware sets a CSRF cookie and generates a masked token
  2. The token is available in templates via the {{ csrfToken }} function (provided by HasRequestFuncMap)
  3. Templates include the token in forms as a hidden field
  4. On unsafe requests (POST, PUT, DELETE, PATCH), the middleware validates the submitted token against the cookie

Using Tokens in Templates

The CSRF app implements HasRequestFuncMap and provides a csrfToken function available in all templates:

{{ define "notes/create" -}}
<form method="POST" action="/notes">
    <input type="hidden" name="gorilla.csrf.Token" value="{{ csrfToken }}">
    <input type="text" name="title" placeholder="Title">
    <button type="submit">Create</button>
</form>
{{- end }}

For AJAX requests, send the token in the X-CSRF-Token HTTP header:

fetch("/api/submit", {
    method: "POST",
    headers: {
        "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content,
    },
    body: JSON.stringify(data),
});

Include a meta tag in your layout template:

<meta name="csrf-token" content="{{ csrfToken }}">

Go API

The token is also available in Go code via the context:

import "github.com/oliverandrich/burrow/contrib/csrf"

token := csrf.Token(r.Context())

Configuration

Flag Env Var Default Description
--csrf-key CSRF_KEY auto-generated 32-byte hex auth key

CSRF Key

If no key is provided, one is auto-generated and logged to stdout. Tokens will not persist across server restarts. For production, always set CSRF_KEY.

Generate a key:

openssl rand -hex 32

  • HttpOnly: true — not accessible from JavaScript
  • Secure — set automatically when base URL is HTTPS
  • SameSite: Lax — prevents cross-site cookie sending
  • Path: / — available on all routes

Interfaces Implemented

Interface Description
burrow.App Required: Name(), Register()
Configurable CLI flag for auth key
HasMiddleware CSRF protection middleware
HasRequestFuncMap Provides csrfToken function to templates