CSRF exploits the fact that your browser automatically attaches cookies (including Session IDs) to every request for a specific domain. If you are logged into your bank, and you visit a malicious site, that malicious site can send a form to your bank. Your browser will attach your Bank Session Cookie, and the bank will accept it as if YOU sent it.
The Attack Scenario
1. You log into bank.com.
2. You browse malicious.com in a new tab.
3. malicious.com has a hidden image:
<img src="http://bank.com/transfer?to=Hacker&amount=1000">
4. Your browser tries to load the image. It sends a GET request to bank.com.
5. Because of the cookie, the Bank processes the transfer.
1. Why did this work? (Stateless HTTP)
The web server cannot distinguish between:
- A request initiated by the user clicking a button on `bank.com`.
- A request initiated by a script on `malicious.com`.
It only checks "Is the cookie valid?". Yes. "Okay, do it."
2. Defenses: Anti-CSRF Tokens
The only reliable defense is to require a secret value that the attacker cannot know.
The Synchronizer Token Pattern:
1. When you visit the bank form, the server generates a random token: `csrf_token="abc123"`.
2. It embeds this token in a hidden HTML field.
3. When you submit, the server checks if `POST['csrf_token'] == Session['csrf_token']`.
The attacker on `malicious.com` cannot see this token (due to Same-Origin Policy) and thus cannot forge a valid request.
3. SameSite Cookies
A modern browser feature. You can tell the browser:
Set-Cookie: session_id=xyz; SameSite=Strict
This tells the browser: "If the request comes from an external site (like clicking a link from Facebook), DO NOT send this cookie."
This kills CSRF entirely for GET requests.