Cross-Site Request Forgery (CSRF)
1. Definition
Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they are currently authenticated.
It exploits the “Ambient Authority” mechanism of web browsers: credentials (session cookies, basic auth headers) are automatically included in cross-site requests based on the target domain, regardless of the request’s origin.
2. Technical Explanation
The core vulnerability lies not in the server’s authentication logic, but in its failure to verify the intentionality of a request.
When a user logs into bank.com, the browser stores a session cookie session_id=xyz. If the user then visits evil.com, and evil.com contains the following code:
<form action="https://bank.com/transfer" method="POST" id="hack">
<input type="hidden" name="amount" value="1000">
<input type="hidden" name="to" value="attacker">
</form>
<script>document.getElementById('hack').submit();</script>The browser will execute this POST request. Crucially, the browser attaches the session_id=xyz cookie to this request because the destination is bank.com. The server receives a valid session cookie and processes the transfer, unaware that the request originated from evil.com.
3. Attack Flow (Sequence Diagram)
sequenceDiagram
participant Victim as User Browser
participant Attacker as Evil.com
participant Server as Bank.com (Vulnerable)
Note over Victim, Server: User is authenticated (Cookie: session=123)
Victim->>Attacker: 1. Visits malicious page
Attacker-->>Victim: 2. Returns page with hidden auto-submitting form
Note over Victim: Browser parses HTML<br/>Found <form action="bank.com">...
Victim->>Server: 3. POST /transfer (Cookie: session=123)
Note right of Victim: Browser AUTOMATICALLY adds cookies<br/>Referer: https://evil.com
Server-->>Server: 4. Validates Cookie (Pass)<br/>5. Executes Transfer
Server-->>Victim: 6. 200 OK (Transfer Successful)4. Real-World Case Study: Netflix (2006)
Target: Netflix “Add to Rental Queue” functionality. Vulnerability Class: GET-based CSRF.
In 2006, researchers discovered that Netflix’s “Add to Queue” action was performed via a simple GET request: GET http://www.netflix.com/AddToQueue?movieid=70011204
The Attack: An attacker could host a webpage containing an image tag: <img src="http://www.netflix.com/AddToQueue?movieid=70011204" />
When a logged-in Netflix user loaded the attacker’s page:
- The browser attempted to fetch the “image” from Netflix.
- The request included the user’s active Netflix authentication cookies.
- Netflix’s server processed the GET request and added “SpongeBob SquarePants” (or any movie) to the victim’s rental queue.
- While seemingly low-impact, this demonstrated how state changes could be triggered without user consent.
Impact: Widespread manipulation of user data. It forced Netflix (and the industry) to strictly enforce POST methods for state changes and implement anti-CSRF tokens.
5. Detailed Defense Strategies
A. Synchronizer Token Pattern (Stateful)
This is the most robust defense.
Generation: The server generates a cryptographically strong, unique, and unpredictable random token (CSRF Token) for the user’s session.
Transmission: This token is embedded in the HTML form as a hidden field (or sent as a specific HTTP header for AJAX).
<input type="hidden" name="csrf_token" value="raNDomStr1ng...">Validation: On state-changing requests (POST, PUT, DELETE), the server compares the submitted token with the one stored in the session.
- If missing or mismatched -> Reject (403 Forbidden).
- Note: The token must NOT be stored in a cookie that is automatically sent.
B. Double Submit Cookie (Stateless)
Useful for stateless backends (like REST APIs).
- The server sets a random value in a cookie (e.g.,
csrf_cookie) AND the frontend reads it and sends it in a custom header (e.g.,X-CSRF-Token). - The server validates that
Cookie.csrf_cookie === Header.X-CSRF-Token. - Why it works: An attacker can trigger a request that sends the cookie, but due to Same-Origin Policy (SOP), they cannot read the cookie value to set the custom header.
C. SameSite Cookie Attribute
A browser-level defense (Defense in Depth). Set the SameSite attribute on session cookies:
SameSite=Strict: Cookies are never sent on cross-site requests. (Best security, impacts UX).SameSite=Lax: Cookies are sent only on top-level navigations (GET) that are safe. (Good balance).
Set-Cookie: session_id=xyz; SameSite=Lax; Secure; HttpOnlyD. Standard Headers Verification
Check Origin and Referer headers.
- If
Originis present, verify it matches the target domain. - If
Originis null, checkReferer. - Warning: These headers can be omitted or stripped by browsers (or proxies) for privacy reasons, so this should be a secondary “defense-in-depth” measure rather than a primary one.
