CSRF explained: how it works and how to prevent it
Browsers attach cookies automatically, and attackers abuse that. Learn how CSRF works and the modern defences.

Cross-site request forgery (CSRF) tricks a logged-in user's browser into sending an unwanted request to a site where they are authenticated. The site cannot tell it apart from a real action, because the browser automatically sends the cookies.
How an attack works
- You log in to
bank.example. Your browser stores a session cookie. - In another tab you visit
evil.example, which has a hidden form that submits tobank.example/transferwith the attacker's account as the target. - Your browser sends the request with your cookie. The bank sees a valid session and processes it.
The attacker never sees the response and does not steal the cookie. They simply cause an action (change email, transfer money, change a password, delete data).
Why it works
- Cookies are sent with requests to their site no matter which page started the request.
- The server relies only on the cookie to know who is calling.
Defences
1. SameSite cookies. Set SameSite=Lax (or Strict) on session cookies. The browser then does not send them on cross-site POST requests. Modern browsers treat Lax as the default if the attribute is missing, but set it explicitly. This alone blocks most classic CSRF.
2. CSRF tokens. Give each session (or form) a random, unguessable token. Include it in every state-changing request (a hidden form field or a header). The server rejects requests without a valid token. An attacker on another site cannot read it.
3. Check the Origin / Referer header. For state-changing requests, verify the request comes from your own origin.
4. Custom headers for APIs. Require a header such as X-Requested-With or a bearer token. Cross-site forms cannot set custom headers, and cross-origin fetch with custom headers needs CORS approval.
5. Never change state with GET. Links and images can trigger GET requests. Use POST, PUT or DELETE for changes.
6. Re-authenticate for critical actions. Ask for the password or a one-time code before changing email, password or payment details.
What does not help
- Only checking that the user is logged in.
- Keeping the session cookie secret from JavaScript (HttpOnly) — useful against XSS but not CSRF.
- Using POST instead of GET alone. Forms can POST cross-site.
- Secret URLs.
APIs using Authorization headers
If your API uses a token in the Authorization header that JavaScript adds (not a cookie), browsers do not add it automatically, so classic CSRF does not apply. But if you store such tokens somewhere reachable by script, XSS becomes the bigger risk.
CSRF and XSS
If a site has XSS, an attacker can read CSRF tokens and bypass them. Fix XSS first.
Takeaway: set SameSite cookies, add CSRF tokens (or Origin checks) to every state-changing request, never change state with GET, and re-authenticate for sensitive actions.
Web Security series, Part 1 (injection and access control): 3 of 4. Previous: Cross-site scripting (XSS): types, impact and prevention.

