Luke a Pro

Luke Sun

Developer & Marketer

🇺🇦
EN||

Cross-Site Request Forgery (CSRF)

| , 4 minutes reading.

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:

  1. The browser attempted to fetch the “image” from Netflix.
  2. The request included the user’s active Netflix authentication cookies.
  3. Netflix’s server processed the GET request and added “SpongeBob SquarePants” (or any movie) to the victim’s rental queue.
  4. 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.

  1. Generation: The server generates a cryptographically strong, unique, and unpredictable random token (CSRF Token) for the user’s session.

  2. 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...">
  3. 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.

Useful for stateless backends (like REST APIs).

  1. 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).
  2. The server validates that Cookie.csrf_cookie === Header.X-CSRF-Token.
  3. 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.

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; HttpOnly

D. Standard Headers Verification

Check Origin and Referer headers.

  • If Origin is present, verify it matches the target domain.
  • If Origin is null, check Referer.
  • 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.

6. References