Cross Site Request Forgery

Cross-Site Request Forgery (CSRF) is a web security vulnerability that allows attackers to induce users to perform actions they do not intend to perform. It exploits the trust that a web application has in the user's browser. CSRF attacks specifically target state-changing requests (like changing passwords or making purchases), not data theft, since the attacker cannot see the response to the forged request.

How an Attacker Can Exploit This Vulnerability

  1. Identify a Target: The attacker identifies a vulnerable web application that performs actions based on authenticated requests.

  2. Create a Malicious Request: The attacker crafts a request that will perform an action on the target web application.

  3. Induce Victim to Execute the Request: The attacker tricks the victim into executing the malicious request by embedding it in a webpage, email, or another delivery method. This can be done via hidden forms, image tags, or other means.

  4. Action Performed: When the victim’s browser sends the request, it includes the session cookies or authentication tokens, causing the action to be performed with the victim's privileges.

Potential Damage of a CSRF Attack

  • Account Takeover: Changing the victim's email address or password.

  • Unauthorized Transactions: Performing financial transactions without the victim's consent.

  • Data Manipulation: Deleting or altering data, changing settings, etc.

  • Service Misuse: Subscribing to or unsubscribing from services, modifying access controls, etc.

Brief Use Cases

  1. Changing User Account Details: An attacker can change the victim’s email address or password, leading to an account takeover.

  2. Performing Financial Transactions: Unauthorized fund transfers or purchases.

  3. Changing User Settings: Altering user preferences or security settings.

  4. Exploiting Administrative Functions: Forcing actions that require administrative privileges, such as deleting users or altering access levels.

Protecting a Web Application from CSRF

Anti-CSRF Tokens

  • Implementation: Generate a unique token for each session and include it in all forms and state-changing requests. Validate the token on the server side.

  • Requirements: Modify forms to include tokens, implement server-side validation.

SameSite Cookies

  • Implementation: Use the SameSite attribute in cookies to restrict them to same-site requests.

  • Requirements: Update server configurations to set SameSite attribute on cookies.

Example use

Good Example - 1

Using the SameSite attribute correctly to enhance security by restricting the cookie to same-site requests:

httpCopy codeSet-Cookie: sessionId=abc123; Secure; HttpOnly; SameSite=Strict

Explanation:

  • sessionId=abc123: The cookie name and value.

  • Secure: Ensures the cookie is only sent over HTTPS.

  • HttpOnly: Prevents the cookie from being accessed via JavaScript, mitigating XSS attacks.

  • SameSite=Strict: The cookie will only be sent for requests originating from the same site, providing strong protection against CSRF attacks.

Bad Example - 1

Misusing the SameSite attribute or omitting it entirely, potentially leading to security vulnerabilities:

httpCopy codeSet-Cookie: sessionId=abc123; Secure; HttpOnly

Explanation:

  • sessionId=abc123: The cookie name and value.

  • Secure: Ensures the cookie is only sent over HTTPS.

  • HttpOnly: Prevents the cookie from being accessed via JavaScript, mitigating XSS attacks.

  • Missing SameSite attribute: Without the SameSite attribute, the cookie is sent with both same-site and cross-site requests by default, which could expose the application to CSRF attacks.

Bad Example - 2

Using an inappropriate value for the SameSite attribute:

Set-Cookie: sessionId=abc123; Secure; HttpOnly; SameSite=None

Explanation:

  • sessionId=abc123: The cookie name and value.

  • Secure: Ensures the cookie is only sent over HTTPS.

  • HttpOnly: Prevents the cookie from being accessed via JavaScript, mitigating XSS attacks.

  • SameSite=None: While this allows the cookie to be sent with cross-site requests, it can only be secure if combined with Secure. If Secure is not present, it leaves the application vulnerable to CSRF attacks.

Best Practices for Implementing SameSite Cookies

  1. Strict:

    • Use SameSite=Strict for cookies containing sensitive information or those used in critical operations (e.g., authentication cookies).

    • Example:

      Set-Cookie: authToken=xyz789; Secure; HttpOnly; SameSite=Strict
  2. Lax:

    • Use SameSite=Lax for cookies that should generally be sent in same-site contexts but still allow some cross-site requests (e.g., navigations from external links).

    • Example:

      Set-Cookie: trackingId=def456; Secure; HttpOnly; SameSite=Lax
  3. None:

    • Use SameSite=None only when cross-site requests are necessary and ensure the Secure attribute is present to enforce HTTPS.

    • Example:

      Set-Cookie: thirdParty=ghi123; Secure; HttpOnly; SameSite=None
  1. Custom Headers

    • Implementation: Require custom headers (e.g., X-CSRF-Token) for state-changing requests.

    • Requirements: Modify AJAX requests to include custom headers, and implement server-side validation.

  2. Double Submit Cookies

    • Implementation: Send a CSRF token as a cookie and as a request parameter. Validate that both match.

    • Requirements: Implement logic to set cookies and validate tokens on the server.

  3. Content Security Policy (CSP)

    • Implementation: Use CSP to mitigate the risk by defining where requests can be sent from.

    • Requirements: Configure CSP headers to limit allowable sources.

Detailed Implementation Steps

  1. Anti-CSRF Tokens

    • Backend: Generate a token and store it in the session or a secure store.

    • Frontend: Include the token in all form submissions and AJAX requests.

    • Validation: Check the token on the server against the stored token before processing the request.

  2. SameSite Cookies

    • Backend: Set the SameSite attribute for cookies to Strict or Lax.

    • Example (Node.js/Express):

      app.use(session({
        secret: 'secret',
        resave: false,
        saveUninitialized: true,
        cookie: { sameSite: 'Strict' }
      }));
  3. Custom Headers

    • Frontend: Add a custom header to AJAX requests.

    • Backend: Validate the presence of the custom header.

    • Example (AJAX with jQuery):

      $.ajaxSetup({
        headers: { 'X-CSRF-Token': 'your-csrf-token' }
      });
  4. Double Submit Cookies

    • Backend: Set a CSRF token as a cookie.

    • Frontend: Include the same token in a hidden form field or request parameter.

    • Validation: Ensure the token in the request matches the token in the cookie.

  5. Content Security Policy (CSP)

    • Backend: Configure CSP headers to allow only trusted sources for requests.

    • Example (Express):

      app.use((req, res, next) => {
        res.setHeader('Content-Security-Policy', "default-src 'self'");
        next();
      });

By implementing these protections, you can significantly reduce the risk of CSRF attacks on your web applications.

Last updated

Was this helpful?