CSRF (Frontend Standard)
This document defines the CSRF protection standard for Next.js apps using cookie-based authentication.
Why CSRF matters here
Because the browser automatically sends cookies, an attacker can sometimes trigger authenticated requests from a malicious site. CSRF protections are required for all unsafe methods:
POST,PUT,PATCH,DELETE
Required layers (defense-in-depth)
For every unsafe request hitting the BFF (/api/v1/*), enforce:
- SameSite cookies
- Prefer
SameSite=Lax. - Use
SameSite=Strictonly if product flows allow it.
- Prefer
- CSRF token requirement
- Use a token that the attacker cannot read/copy cross-site.
- Origin/Referer checks
- Reject unsafe requests when
Origin/Refererdoes not match your own origin.
- Reject unsafe requests when
Standard pattern: double-submit token
This pattern is simple and works well for BFFs:
- Server sets a non-HttpOnly CSRF cookie (so browser JS can read it) e.g.,
csrf_token. - Client sends the token in a header (or body) e.g.,
X-CSRF-Token. - BFF rejects if:
- cookie missing, or header missing
- header token != cookie token
- origin/referrer mismatch
Rule: the CSRF token must be independent from auth cookies and must be validated on the server.
Recommended header/cookie names (generic defaults)
- Cookie:
csrf_token - Header:
X-CSRF-Token
Projects may rename these, but must document it.
Standard BFF validation algorithm (pseudocode)
function validateCsrf(req: Request): void {
if (!isUnsafeMethod(req.method)) return
assertSameOrigin(req.headers.get("origin"), req.headers.get("referer"))
const csrfCookie = readCookie(req, "csrf_token")
const csrfHeader = req.headers.get("x-csrf-token")
if (!csrfCookie || !csrfHeader) throw new Error("CSRF token missing")
if (!timingSafeEqual(csrfCookie, csrfHeader)) throw new Error("CSRF token mismatch")
}
Notes
- CSRF validation is standardized in the Next.js BFF.
- The backend may add its own CSRF protections, but the minimum bar is enforced at the BFF.