CSRF Attack and Defense Detailed Explanation

CSRF Attack and Defense Detailed Explanation

I. CSRF Attack Description

CSRF (Cross-Site Request Forgery) is a type of malicious attack. Attackers trick users into performing unintended actions on a web application where they are currently logged in. Its core principle is: Exploiting the user's established login state (e.g., cookies) on another website by forging requests, causing the user to execute actions predetermined by the attacker without their knowledge.

For example: Suppose you are logged into online bank A, and your login session cookie is valid. You then visit a malicious website B. Page B contains a hidden image tag with its src pointing to bank A's transfer API (e.g., <img src="https://bank-a.com/transfer?to=attacker&amount=1000">). When the browser loads this image, it automatically sends a GET request to that API, carrying your login cookie for bank A. Bank A validates the cookie as valid and executes the transfer. This is a classic CSRF attack.

II. Attack Principle and Prerequisites

To successfully execute a CSRF attack, the following three key conditions must be met simultaneously:

  1. Exploitable Interface on the Target Website: The application has an interface that can perform sensitive operations (e.g., changing passwords, transferring funds, posting content), and this interface relies solely on cookies or "browser-automatically-added credentials" for authentication.
  2. User is Logged into the Target Website: The user's browser holds a valid login session (Session Cookie) for the target website, and this cookie has not expired.
  3. User is Tricked into Visiting a Malicious Page: The attacker induces the user to visit a specially crafted page (e.g., via phishing emails, malicious websites) that automatically sends requests to the target website's interface.

III. Common Attack Implementation Methods

Attackers forge requests in various ways, primarily categorized into three types:

  1. GET Request Attack

    • Method: Place malicious request parameters directly in the URL, triggered by the src or href attributes of tags like <img>, <script>, <link>, <iframe>. The browser automatically initiates the GET request.
    • Example:
      <!-- When a user visits a page containing this code, a transfer is silently initiated -->
      <img src="https://bank.com/transfer?to=hacker&amount=100000" width="0" height="0">
      
  2. POST Request Attack

    • Method: Construct a hidden <form> on the malicious page and submit it automatically (using JavaScript's submit() method).
    • Example:
      <body onload="document.forms[0].submit()">
        <form action="https://bank.com/change_password" method="POST">
          <input type="hidden" name="new_password" value="hacker_controlled" />
        </form>
      </body>
      
  3. Other HTTP Method Attacks

    • For requests like PUT, DELETE, these can also be implemented by constructing XMLHttpRequest or Fetch requests, but they are usually restricted by the browser's Same-Origin Policy (CORS), depending on the target server's CORS configuration.

IV. Detailed Defense Strategies

The core idea of defending against CSRF is to add verification information that the attacker cannot predict or forge. The following are layered defense solutions:

Layer 1: Origin Detection (Basic Defense)

Utilize the Origin and Referer headers in HTTP requests, which inform the server of the request's source address.

  • Origin Header: Indicates which site (protocol + domain + port) the request originated from. It may not be sent for same-origin requests or in some specific cases (e.g., IE11).
  • Referer Header: Contains the complete URL of the request origin.
  • Defense Steps:
    1. When processing sensitive requests (non-GET), the server checks the Origin or Referer header.
    2. Determines if its value matches the server's own domain.
    3. If it does not match, the request is rejected.
  • Advantages: Simple to implement.
  • Disadvantages:
    • Privacy or security policies may cause browsers not to send these headers.
    • Older browsers may have vulnerabilities.
    • Should not be used as the sole defense; it should be combined with other methods.

Layer 2: CSRF Token (Mainstream and Most Effective Solution)

This is currently the most reliable and widely used defense mechanism.

  • Principle: Generate a random, unpredictable token in the user's session. This token is carried in requests that need protection (e.g., forms, AJAX requests). The server verifies the token's validity when processing the request.

  • Detailed Process:

    1. Generate Token: When a user accesses the application, the server generates a random CSRF Token for their session.
    2. Deliver Token: The server embeds this token into forms returned to the user (as a hidden field) or sets it in a global variable (e.g., a meta tag) for frontend JavaScript to retrieve.
      <!-- Form Example -->
      <form action="/transfer" method="POST">
        <input type="hidden" name="csrf_token" value="randomly_generated_string">
        <!-- ... Other form fields -->
      </form>
      
    3. Include Token: When the user submits the form or initiates an AJAX request, the frontend code must include this token in the request (as a form field or request header, e.g., X-CSRF-TOKEN).
    4. Server Verification: Upon receiving the request, the server retrieves the previously stored token from the session and compares it with the token carried in the request.
      • If they match, the request is legitimate, and the operation is executed.
      • If they don't match, are missing, or expired, the request is deemed forged and immediately rejected with an error.
  • Why Does It Defend Against CSRF?

    • Protected by Same-Origin Policy: Malicious website B cannot read the CSRF Token value from the user's session on website A via JavaScript (restricted by the Same-Origin Policy).
    • Unpredictability: The attacker cannot guess or forge the correct token value.

Layer 3: Double Submit Cookie (Alternative Solution)

This solution places the token in a cookie but requires frontend scripts to read it and pass it as a request parameter or header.

  • Process:
    1. When a user visits, the server sets a cookie in the response (e.g., csrf_token=random_string).
    2. Frontend JavaScript reads the value of this cookie.
    3. When initiating a request, this value is sent as a parameter (e.g., x-csrf-token) or a custom request header (e.g., X-CSRF-TOKEN).
    4. Upon receiving the request, the server compares the token value from the cookie with the token value from the parameter/header.
  • Advantages: Relatively simple to implement, no need to store the token server-side for each session (though the cookie itself is part of the session).
  • Disadvantages:
    • If the website has an XSS vulnerability, attackers can read the cookie, rendering this solution ineffective.
    • Subdomain security must be ensured; otherwise, cookies across subdomains might be tampered with.

Layer 4: Utilizing SameSite Cookie Attribute (Powerful Modern Browser Supplement)

This is a browser-provided mechanism to curb CSRF at its source.

  • Principle: By setting the SameSite attribute of a cookie, control whether the cookie is sent in cross-site requests.
  • Three Modes:
    • Strict: Most strict. Cookies are sent only in same-site requests (i.e., when the current page URL's eTLD+1 matches the request target URL's eTLD+1). Completely prevents CSRF but may affect user experience (e.g., clicking a link from an external site may lose login state).
    • `Lax**: Loose mode. Cookies are sent in safe cross-site requests (e.g., GET requests, page navigation) but not in unsafe cross-site POST requests. This is the recommended default setting for many sites today, balancing security and usability.
    • None: Cookies are sent in all contexts but must also have the Secure attribute set (i.e., transmitted only over HTTPS).
  • Setting Example (in HTTP response header):
    Set-Cookie: sessionid=abc123; SameSite=Lax; Secure
    

Summary and Best Practices

  1. Preferred Solution: CSRF Token is the most robust cornerstone for defending against CSRF attacks. Ensure tokens are random, single-use (or short-lived), and bound to the user session.
  2. Powerful Supplement: Set the SameSite=Lax or Strict attribute for all authentication-related cookies. This fundamentally prevents most types of CSRF attacks.
  3. Layered Defense: For critical operations, combine the use of Tokens and the SameSite attribute. Additionally, use origin detection for sensitive requests as an extra safeguard.
  4. Security Awareness: Ensure the application has no XSS vulnerabilities, as XSS can bypass most CSRF defenses (e.g., stealing tokens).
  5. Avoid Using GET for State-Changing Actions: Strictly adhere to HTTP semantics. GET requests should only be used for retrieving data, not for performing any actions with side effects. This prevents simple GET-based CSRF attacks.