Intermediate·10 min read·Updated 2026-10-15

CSRF Attacks: Prevention with SameSite Cookies & Anti-CSRF Tokens

Original WeSecureX guide for authorized testing of sites you own. Linked Sources are citations for verification - not copied articles. Ads are not served on this page.

Cross-Site Request Forgery exploits the fundamental trust relationship between a web application and a user's browser. While Cross-Site Scripting (XSS) focuses on executing malicious script inside the application's origin, CSRF tricks the browser into sending forged requests from an external origin. Understanding browser ambient authority, SameSite cookie policies, and anti-CSRF token architectures is essential for securing web applications and APIs against unauthorized state modification.

CSRF Attacks: Prevention with SameSite Cookies & Anti-CSRF Tokens
CSRF attacks · WeSecureX Research Lab
Quick Answer

Cross-Site Request Forgery (CSRF / CWE-352) is an attack that tricks a victim's authenticated browser into executing unwanted state-changing actions on a trusted web application. Because browsers historically included session cookies automatically with all cross-site requests (ambient authority), vulnerable servers could not distinguish legitimate user actions from malicious cross-origin form submissions. Prevention relies on SameSite cookie attributes (Lax/Strict) and cryptographic anti-CSRF tokens.

Key Takeaways
  • CSRF exploits browser ambient authority to forge state-changing actions under an authenticated session.
  • SameSite=Lax (default in modern browsers) provides baseline transport-level protection for POST forms.
  • GET requests must never perform state changes or database mutations.
  • CORS restricts response reading, NOT request execution; it does not protect against CSRF.
  • Anti-CSRF tokens bind actions to user intent and cannot be forged across origins.
Visual Diagram · CSRF Attack Lifecycle & Anti-CSRF Token Validation
1

1. Victim Visits Malicious Web Page

Authenticated user visits attacker site containing hidden auto-submitting POST form targeting vulnerable app.

2

2. Browser Attaches Ambient Cookies

Browser automatically attaches session cookies to cross-site request, passing default authentication.

3

3. Anti-CSRF Token & SameSite Check

Server rejects request lacking unique cryptographically signed anti-CSRF token or flagged SameSite=Strict.

4

4. Continuous Session & Form Audit

Form endpoints and HTTP headers undergo automated auditing on [WeSecureX Security Console](/scanner).

ShareShare on XLinkedIn

How CSRF Exploits Ambient Browser Authority

Cross-Site Request Forgery (CSRF) tricks an authenticated browser into submitting unauthorized requests to a vulnerable application.

SameSite Cookie Modes vs. Request Context Matrix

SameSite ModeTop-Level GET Navigation (Link Click)Cross-Site POST Form SubmissionThird-Party Image / Iframe RequestCSRF Protection Level
`SameSite=Strict`Cookie Blocked (Omitted)Cookie BlockedCookie BlockedMaximum Protection (User appears logged out on external links)
`SameSite=Lax` (Default)Cookie SentCookie BlockedCookie BlockedBalanced Protection (Prevents state-changing POST attacks)
`SameSite=None; Secure`Cookie SentCookie SentCookie SentZero Protection (Must mandate anti-CSRF tokens)

The web security model is built on origin isolation, but HTTP was originally designed to allow cross-origin document embedding (e.g., loading images, submitting forms, or navigating between sites). Historically, whenever a browser dispatched an HTTP request to example.com, it automatically attached all cookies stored for example.com - regardless of which website originated the request. This behavior is known as ambient authority.

In a classic CSRF scenario:

  1. A user logs into their banking portal at bank.com and receives an authentication session cookie.
  2. Without logging out, the user visits a malicious website attacker.com.
  3. The malicious website contains a hidden form that auto-submits a POST request to bank.com/transfer with attacker parameters.
  4. The user's browser transmits the request along with the user's valid session cookie.
  5. The banking server validates the cookie and executes the unauthorized transfer.
html
<!-- Example: Malicious form hosted on attacker.com -->
<form id="csrfForm" action="https://bank.com/api/transfer" method="POST">
  <input type="hidden" name="recipient" value="attacker_account" />
  <input type="hidden" name="amount" value="10000" />
</form>
<script>
  // Auto-submit immediately upon page load
  document.getElementById('csrfForm').submit();
</script>

Modern Browser Defense: The SameSite Cookie Attribute

The SameSite cookie attribute instructs modern browsers whether to attach cookies to cross-site requests. It is the primary transport-level defense against CSRF:

SameSite=Strict

The cookie is NEVER sent in cross-site requests. If a user clicks a link to example.com from an external email or search engine, the browser does NOT send the cookie on that initial navigation. This provides maximum security for high-value banking and administrative actions.

SameSite=Lax (Default in Modern Browsers)

The cookie is withheld on cross-site sub-requests (such as <img>, <iframe>, and cross-site POST forms), but IS included when the user navigates to the origin via a 'safe' top-level GET request (e.g., following a link). This balances usability with robust CSRF protection for state-changing POST requests.

SameSite=None

Cookies are sent in all cross-site contexts (e.g., embedded iframes, third-party widgets). It MUST be paired with the Secure flag (SameSite=None; Secure). Applications using SameSite=None must rely entirely on explicit anti-CSRF tokens.

The Synchronizer Token Pattern (STP)

The Synchronizer Token Pattern is the gold-standard application-level defense against CSRF. When a user establishes a session, the server generates a cryptographically strong pseudo-random token and binds it to the user's session.

When rendering forms or issuing API mutations, the server injects this token into the client (via a hidden form field or custom HTTP header). When processing state-changing requests (POST, PUT, DELETE), the server compares the submitted token against the session token. Because the Same-Origin Policy prevents attacker.com from reading tokens on bank.com, the attacker cannot forge a valid request.

typescript
// Node.js Express CSRF Token Verification Middleware
import crypto from 'crypto';
import type { Request, Response, NextFunction } from 'express';

export function verifyCsrfToken(req: Request, res: Response, next: NextFunction) {
  // Safe HTTP methods do not change state
  if (['GET', 'HEAD', 'OPTIONS'].includes(req.method)) {
    return next();
  }

  const clientToken = req.headers['x-csrf-token'] || req.body?._csrf;
  const sessionToken = req.session?.csrfToken;

  if (!clientToken || !sessionToken || !crypto.timingSafeEqual(Buffer.from(clientToken), Buffer.from(sessionToken))) {
    return res.status(403).json({ error: 'CSRF token verification failed' });
  }

  next();
}

Why CORS Does NOT Protect Against CSRF

A frequent and dangerous misconception among developers is believing that Cross-Origin Resource Sharing (CORS) prevents CSRF attacks.

CORS is a browser mechanism that restricts whether a web page can read the response of a cross-origin request. However, CSRF is an attack on state execution, not data retrieval. When a malicious form submits a POST request cross-site, the browser dispatches the request and the server executes the database mutation - even if CORS blocks the attacker from reading the response! CORS does not replace anti-CSRF defenses.

The Chromium 2-Minute 'Lax-allowing-unsafe' Exception

A critical security nuance in modern Chromium-based browsers (Chrome, Edge, Brave, Opera) is the 2-minute Lax exception:

When a cookie is created without an explicit SameSite attribute, Chromium defaults to SameSite=Lax. However, to prevent breaking legacy single sign-on (SSO) redirect flows, Chromium implements a temporary exemption: for the first 120 seconds after creation, top-level cross-site POST requests are permitted to include the cookie!

This means an attacker who induces a victim to click a link within 2 minutes of logging in can successfully execute CSRF if your application relies solely on default SameSite settings. Explicit cryptographic Anti-CSRF tokens or custom request headers (`X-Requested-With`) remain strictly mandatory. You can audit CSRF defenses across your endpoints using the WeSecureX Vulnerability Explorer.

Apply it with WeSecureX

Add a hostname you own or are allowed to test, run a scan, and open the findings for that target. A confirmed result includes the request WeSecureX sent and the response the site returned, so you can reproduce it, fix it in your own application, and rescan the same host to confirm the issue is gone. WeSecureX is automated testing, not a manual penetration test, and a clean report is not a promise that every weakness is gone.

Checks that belong with this topic

  • Set `SameSite=Lax` or `SameSite=Strict` on all authentication and session cookies.
  • Ensure all GET, HEAD, and OPTIONS requests are strictly read-only and idempotent.
  • Implement Synchronizer Token Pattern or HMAC-signed Double-Submit Cookies on all state-changing endpoints.
  • Use constant-time comparisons (`crypto.timingSafeEqual`) to validate tokens.
  • Require custom request headers (e.g., `X-Requested-With` or `X-CSRF-Token`) for JSON API mutations.
  • Re-authenticate users before high-risk actions (password changes, email updates, wire transfers).

Common Mistakes to Avoid

❌Performing state-changing actions via GET requests (e.g., `/user/delete?id=5`)

Why it happens: Developers create simple links for convenience instead of forms or POST requests.

Why it matters: GET requests can be triggered by simple `<img>` tags (`<img src='bank.com/transfer?amount=100'>`), completely bypassing `SameSite=Lax` protection.

Correct approach: Strictly adhere to HTTP specifications: GET, HEAD, and OPTIONS must be safe and idempotent. All mutations must use POST, PUT, PATCH, or DELETE.

❌Assuming CORS configuration protects against CSRF

Why it happens: Developers see 'CORS error' in the console and assume the request was blocked.

Why it matters: CORS blocks the client from reading the response; the server still receives, parses, and executes the state-changing request.

Correct approach: Implement SameSite cookies and anti-CSRF tokens regardless of CORS configuration.

❌Using static or predictable CSRF tokens

Why it happens: Developers derive tokens from user IDs or timestamps.

Why it matters: Predictable tokens allow attackers to calculate the required token and forge requests successfully.

Correct approach: Generate tokens using a Cryptographically Secure Pseudo-Random Number Generator (CSPRNG, e.g., `crypto.randomBytes(32)`).

❌Comparing CSRF tokens with standard equality operators (`===`)

Why it happens: Developers write `if (clientToken === sessionToken)`.

Why it matters: Standard string comparisons terminate on the first non-matching byte, exposing the server to timing attacks.

Correct approach: Use constant-time comparison functions like `crypto.timingSafeEqual()`.

Troubleshooting Guide

Problem: Legitimate users receive 403 CSRF verification failed after opening multiple browser tabs

Possible Causes:

  • The server generates a new CSRF token on every page load and overwrites the session token, invalidating tokens in earlier tabs.

How to verify: Open two tabs, submit a form in tab 1, and check for 403 Forbidden.

How to fix: Bind a single CSRF token per user session rather than per request, or implement token rotation with grace periods.

Problem: Mobile app or external API clients fail with CSRF errors

Possible Causes:

  • CSRF middleware is applied globally to all API endpoints, including non-browser clients.

How to verify: Send a request via curl or Postman and inspect for CSRF validation failures.

How to fix: Only enforce CSRF checks on requests authenticated via session cookies; API clients using `Authorization: Bearer <JWT>` are not vulnerable to CSRF.

Actionable Checklist

WeSecureX Platform · Scanner Engine

Automated Vulnerability Scanner

Launch targeted or full-domain security audits to detect OWASP Top 10 vulnerabilities automatically.

Includes: OWASP Top 10 automated test suites · Real-time severity scoring (CVSS v3.1) · Instant remediation code snippets

Frequently Asked Questions

Standard cross-origin HTML forms can only send `application/x-www-form-urlencoded`, `multipart/form-data`, or `text/plain`. However, modern browsers can send cross-origin `application/json` via `fetch()` if CORS is misconfigured. Requiring custom headers (like `X-CSRF-Token`) triggers a browser CORS preflight check, effectively blocking CSRF.

If the JWT is stored in an `HttpOnly` cookie, the application IS vulnerable to CSRF and requires anti-CSRF tokens. If the JWT is stored in memory and sent via the `Authorization: Bearer <token>` header, it is immune to CSRF (though vulnerable to XSS if tokens are exposed).

Chromium introduced a temporary mitigation where cookies without a SameSite attribute default to `Lax`, but permit cross-site POST requests within 2 minutes of creation ('Lax+POST'). Explicitly specifying `SameSite=Lax` or `SameSite=Strict` prevents this behavior.

SameSite=Lax blocks cross-site POST form submissions and cross-site sub-requests (images, iframes). However, Chromium has a temporary 2-minute exception for newly created cookies, so cryptographic anti-CSRF tokens remain necessary.

The client reads a non-HttpOnly random token cookie and copies it into a custom HTTP request header (e.g. X-CSRF-Token). The server compares the cookie value with the header value, blocking cross-origin attackers who cannot read cookies.

Authoritative Sources & References

  • OWASP Cross-Site Request Forgery Prevention Cheat SheetOWASP Foundation (official)
    View Source
  • IETF RFC 6265bis: Cookies: HTTP State Management MechanismIETF (official)
    View Source
  • MDN Web Docs: SameSite cookiesMozilla (technical)
    View Source
  • IETF RFC 6265bis: SameSite Cookie Attribute SpecificationIETF (official)
    View Source

Continue exploring related technical architecture and defensive guides

Security Research & Engineering Articles

All articles