Featured image of post Mitigating CSRF: SameSite Cookie Attributes and CSRF Tokens Featured image of post Mitigating CSRF: SameSite Cookie Attributes and CSRF Tokens

Mitigating CSRF: SameSite Cookie Attributes and CSRF Tokens

Understand how to secure cookie-based session architectures against Cross-Site Request Forgery (CSRF) using SameSite settings and token validation patterns.

Introduction

Cookies are a convenient mechanism for managing user authentication state. When a session ID is stored in a cookie, the browser automatically attaches it to outgoing HTTP requests targeting the domain.

However, this automatic attachment feature is exploited by Cross-Site Request Forgery (CSRF) attacks.

Although modern browsers default to safer cookie behaviors (such as applying SameSite=Lax automatically), developers must understand CSRF defense patterns to prevent serious authentication vulnerabilities. This article reviews SameSite cookie attributes and CSRF token verification patterns.


1. How CSRF Attacks Work

A CSRF attack occurs when a malicious website prompts a victim’s browser to execute unwanted actions on a trusted application where the user is currently authenticated.

  1. The user logs into a banking application (bank.com), and the server stores a session identifier in a local cookie.
  2. While authenticated, the user visits a malicious website (evil.com).
  3. The malicious site runs a script that sends a transfer request (POST /transfer) to the banking application (bank.com).
  4. Because the request targets bank.com, the browser automatically includes the authenticated session cookie.
  5. The bank server processes the request as a legitimate, authenticated session, executing the transaction.

The most effective way to prevent CSRF is by applying the SameSite attribute to session cookies. This setting tells the browser whether cookies should be included in requests originating from third-party (cross-site) domains.

The Three Configuration Options

Set-Cookie: sessionId=abc123; Secure; HttpOnly; SameSite=Lax
SettingBehavior
SameSite=StrictPrevents the browser from sending the cookie in cross-site requests. Even if a user clicks a direct link to your site from an external search engine, they will need to log in again because the cookie is withheld.
SameSite=LaxWithholds cookies on cross-site requests, but allows them when a user navigates to your site by clicking a link (a GET request). This is the industry default for web applications.
SameSite=NoneAttaches cookies to all cross-site requests, including embedded iframe calls. Setting SameSite=None requires the Secure flag (limiting transmissions to HTTPS connections).

Important Limits of SameSite=Lax

While most modern browsers default to SameSite=Lax, relying on it alone leaves potential security gaps:

  1. Incorrect HTTP Method Usage (GET Mutations): If your application performs state changes via GET requests (e.g., GET /delete?id=5), SameSite=Lax will not protect you because Lax allows cookies on cross-site GET link clicks. Always use POST, PUT, or DELETE for state-changing endpoints.
  2. Legacy Browser Support: Older mobile WebView environments and legacy desktop browsers do not recognize the SameSite attribute.

To ensure security across all browser environments, applications should use a CSRF Token verification mechanism. A common pattern for stateless Single Page Applications (SPAs) is the Double Submit Cookie pattern.

How it Works

  1. When a user authenticates, the server generates a random, cryptographically secure token (the CSRF token) and stores it as a client-side cookie.
  2. When the SPA makes a mutation request (POST, PUT, DELETE), JavaScript reads the cookie value and attaches the token to a custom HTTP header (e.g., X-CSRF-Token).
  3. The backend server verifies that the token in the request header matches the token in the cookie.

Why This is Secure

While a malicious site (evil.com) can trigger a form submit that automatically includes your application’s cookies, the browser’s Same-Origin Policy (SOP) prevents third-party JavaScript from reading your cookies to attach the token to a custom HTTP header.

Conclusion

Securing your authentication pipeline against CSRF requires a multi-layered approach:

  1. Ensure all session cookies are configured with SameSite=Lax or Strict and include the HttpOnly flag.
  2. Never allow state changes to occur via GET requests.
  3. Use custom HTTP headers and the Double Submit Cookie pattern to protect mutation endpoints.

Implementing these guidelines will secure your session authentication and protect users from hijacking attacks.