CSRF attacks: how attackers forge requests and how tokens stop them
cross-site request forgery, CSRF token, SameSite cookie attribute, double-submit cookie, CSRF with GET requests, state-changing operations protection
CSRF: Forged Requests from Evil Sites
CSRF (Cross-Site Request Forgery) tricks a logged-in user's browser into making an unintended state-changing request to your application. The browser automatically includes session cookies โ so the server cannot distinguish a legitimate user action from an attacker-initiated one.
The attack
<!-- On evil.com โ victim just needs to view this page -->
<img src="https://bank.com/transfer?to=attacker&amount=500" />
<!-- Browser fetches with bank.com cookies attached automatically -->Why GET requests must be read-only
The above attack works because GET /transfer performs a state change. Always use POST/PUT/DELETE for mutations โ browsers do not auto-trigger those via image or iframe tags. This is also why HTTP semantics define GET as safe (no side effects).
CSRF tokens
The server generates a unique, unpredictable token per session and embeds it in forms. The request must echo it back. Cross-origin JavaScript cannot read your site's HTML, so attackers cannot steal the token:
<form method="POST" action="/transfer">
<input type="hidden" name="csrf_token" value="a1b2c3d4e5f6..." />
<input name="amount" />
</form>SameSite cookies
Set-Cookie: session=abc123; SameSite=Strict; HttpOnly; SecureSameSite=Strict prevents the browser from sending the cookie on any cross-site request โ including form submissions from evil.com. SameSite=Lax (the browser default) blocks cross-site POST but allows cookies on top-level navigations. Modern defense: SameSite=Strict plus CSRF tokens for defense in depth.
