CSRF Protection
Defending against attacks that trick a logged-in user's browser into making unwanted requests to a site they're authenticated to — using the browser's own cookies against them.
What is CSRF protection?
CSRF (Cross-Site Request Forgery) is an attack that tricks a logged-in user’s browser into sending an unwanted request to a site the user is authenticated to — exploiting the fact that browsers automatically attach the site’s cookies to any request to that site, including requests triggered by a different, malicious site. CSRF protection is the set of defenses that stop this. The classic scenario: you’re logged into your bank in one tab; you visit a malicious page in another; that page silently submits a form to yourbank.com/transfer, and because your browser dutifully includes your bank session cookie, the bank sees an authenticated request and executes the transfer — an action you never intended. The attack abuses the browser’s automatic, ambient authentication.
Why it works — and the defenses that stop it
The root of CSRF is ambient authority: cookie-based sessions mean the browser proves your identity automatically on every request to a site, so an attacker doesn’t need to steal your credentials — they just need to get your browser to send a request, and the cookies ride along for free. The defenses all work by requiring proof that a request originated from the legitimate application, not a forged cross-site trigger. Anti-CSRF tokens (the synchronizer token pattern): the server embeds a secret, unpredictable token in each form/page, and legitimate requests must return it; a malicious site can’t read or guess this token (the same-origin policy blocks it from reading the page), so forged requests lack it and are rejected — this is the traditional, robust defense. SameSite cookies: the modern first-line defense — setting cookies to SameSite=Lax (now the browser default) or Strict tells the browser not to send them on cross-site requests, which neutralizes the core mechanism of CSRF for most cases without any token machinery. Double-submit cookie and checking Origin/Referer headers are additional patterns. The current best practice is defense in depth: rely on SameSite cookies as the baseline and use anti-CSRF tokens for sensitive state-changing operations, since SameSite has edge cases and older browser considerations.
The nuances that matter
Several points separate correct CSRF handling from cargo-culted mistakes. First, CSRF only affects requests authenticated by something the browser sends automatically (cookies, HTTP basic auth) — APIs authenticated with a token in an Authorization header (like a JWT the JavaScript explicitly attaches) are not CSRF-vulnerable in the same way, because the attacker’s forged request can’t add that header. This is why token-in-header SPAs and mobile apps often don’t need traditional CSRF tokens, while cookie-session web apps absolutely do — conflating the two leads teams to either add pointless tokens or, worse, omit protection where cookies are the auth. Second, only state-changing requests (POST/PUT/DELETE — transfers, password changes, purchases) need CSRF protection; safe idempotent GETs shouldn’t change state anyway (a GET that mutates data is its own bug and a CSRF hole). Third, CSRF is distinct from XSS — XSS runs attacker script on your page (and can defeat CSRF tokens by reading them), while CSRF makes forged requests from another site without reading your page; you need protection against both, and XSS is the more powerful of the two. It’s a long-standing OWASP concern, though framework defaults (SameSite cookies, built-in CSRF middleware) have made it far more manageable than it once was.
What people get wrong
- Adding CSRF tokens where auth is a header token — cookie-less APIs using
Authorization: Beareraren’t CSRF-vulnerable the same way; the protection belongs on cookie-session apps. - Relying on SameSite alone for sensitive actions: SameSite has edge cases and legacy-browser gaps — pair it with anti-CSRF tokens for high-value state changes (defense in depth).
- GET requests that change state — a state-mutating GET bypasses form-based CSRF defenses and is trivially forgeable; state changes must use POST/PUT/DELETE with protection.
Primary source: OWASP: Cross-Site Request Forgery Prevention Cheat Sheet
Historical figures and technical concepts for informational purposes only. Not technical, professional, legal, or financial advice. Sources: Official Documentation.