Skip to content

CSRF Guard

csrf(*, cookie_name, header_name, safe_methods) — double-submit-cookie CSRF protection.

Signature

def csrf(
    *,
    cookie_name: str = "lauren_csrf",
    header_name: str = "x-csrf-token",
    safe_methods: Iterable[str] = ("GET", "HEAD", "OPTIONS", "TRACE"),
) -> type:
    ...

Parameters:

Parameter Type Default Description
cookie_name str "lauren_csrf" Cookie holding the CSRF token.
header_name str "x-csrf-token" Header the client must echo the token in.
safe_methods iterable ("GET", "HEAD", "OPTIONS", "TRACE") Methods that are exempt from the check.

How it works

Double-submit cookie pattern:

  1. The server issues a random token in a cookie (cookie_name).
  2. On state-changing requests the client must echo the same value in the configured header (header_name).
  3. The guard compares cookie and header values with a constant-time comparison. Absent or mismatched pairs → ForbiddenError (403).

Safe methods (no side effects) skip the check entirely.

Usage

from lauren import controller, post, use_guards
from lauren_guards import csrf

CsrfGuard = csrf()

@use_guards(CsrfGuard)
@controller("/api")
class ApiController:
    @post("/transfer")
    async def transfer(self) -> dict:
        return {"ok": True}

The client must send the token back:

curl -X POST http://localhost:8000/api/transfer \
  -H "Cookie: lauren_csrf=<token>" \
  -H "X-CSRF-Token: <token>"

When to use it

Use it on any controller whose routes are authenticated via cookies (see Session Cookie guard) — cookie auth is what makes CSRF attacks possible in the first place. Token-based clients (Bearer, API key) are not vulnerable to classic CSRF and usually don't need this guard.