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:
- The server issues a random token in a cookie (
cookie_name). - On state-changing requests the client must echo the same value in
the configured header (
header_name). - 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.