Safeguard
Vulnerabilities

What Is a CSRF Token, and How Does It Stop CSRF?

A CSRF token is a random, per-session value a server requires on state-changing requests so a malicious site can't forge one on a logged-in user's behalf.

Safeguard Research Team
Research
5 min read

A CSRF token is a unique, unpredictable value the server generates and embeds in a form or request, then checks against a matching value stored server-side before it processes a state-changing request — the mechanism exists because browsers automatically attach cookies (including session cookies) to any request sent to a domain, whether that request came from the site's own page or from an attacker's page tricking a logged-in user's browser into submitting it. Without a token, the server has no way to tell the difference between a request the user actually intended and one a malicious site quietly triggered on their behalf.

What problem is a CSRF token actually solving?

This is one of the foundational web vulnerability classes covered in our academy material on secure session handling. Cross-site request forgery exploits the fact that authentication via cookies is automatic and origin-blind — if you're logged into your bank in one tab, and a malicious page in another tab submits a form to yourbank.com/transfer, your browser attaches your session cookie to that request exactly as if you'd submitted it yourself. The server sees a validly authenticated request and processes it. The attacker never needed your password or your session token directly; they only needed your browser to make the request while you were already logged in. A CSRF token defeats this because the attacker's page has no way to read the token value the legitimate site embedded in its own form — same-origin policy blocks that read — so the forged request arrives without a valid token and the server rejects it.

How does the token actually get validated?

The server generates a random value, ties it to the user's session, and embeds it in a hidden form field (or a custom request header for API calls) when it renders the page. When the form is submitted, the server compares the submitted token against the one tied to that session and rejects the request if they don't match or if the token is missing entirely. Because the token changes per session (and in stricter implementations, per request), an attacker who doesn't have a live way to read a user's own page has no path to obtaining a valid value to forge.

Why can't the attacker just guess or reuse a token?

Because a well-implemented CSRF token is generated with a cryptographically secure random number generator and is long enough that guessing it is computationally infeasible — the same design principle behind session IDs generally. Reuse across sessions or users is exactly the implementation mistake that breaks this protection: if a token is static per application rather than per session, an attacker can obtain one legitimately (by visiting the page themselves) and reuse that same value in a forged request against a different victim, since the server has nothing session-specific to check it against.

Do SameSite cookies make CSRF tokens unnecessary?

They significantly reduce the attack surface but don't eliminate the need for tokens entirely. Setting a cookie's SameSite attribute to Strict or Lax tells the browser not to send that cookie on cross-site requests, which blocks the classic CSRF pattern at the browser level rather than the application level. In practice, most security guidance recommends both — SameSite cookies as a strong baseline defense, plus CSRF tokens as defense in depth — because SameSite behavior has historical browser inconsistencies, doesn't help for older browsers, and doesn't cover every request pattern (some legitimate cross-site flows require SameSite=None, which reopens the exposure that tokens close).

Where do real implementations of CSRF protection actually break?

The most common failure is a form or API endpoint that was added later and never wired into the framework's token middleware — the login form has a token, but a newly added "delete account" endpoint doesn't, because it was built as a quick API route outside the standard form-handling path. Another common gap is validating the token's presence but not actually checking it matches the session (a token check that always passes as long as any token is present is functionally no protection at all). Static analysis tools that trace state-changing routes and flag ones missing CSRF middleware are useful specifically because this is an easy gap to introduce accidentally in a large codebase, and it's the kind of finding SAST tooling catches reliably across a whole route table rather than relying on a developer remembering to check.

FAQ

Does every request need a CSRF token, or just some? Only state-changing requests (POST, PUT, DELETE, and similar) need protection — a plain GET request that only reads data shouldn't have side effects in the first place, so CSRF protection doesn't apply to it under standard REST conventions.

Are CSRF tokens needed for API-only applications using bearer tokens instead of cookies? Generally no — if authentication is via a bearer token sent in an Authorization header rather than an automatically-attached cookie, the browser won't attach it to a forged cross-site request, which removes the core mechanism CSRF relies on.

What's the difference between a CSRF token and a session token? A session token authenticates who you are; a CSRF token proves the specific request came from a page the server itself rendered, not from a third-party site exploiting an authenticated session. They solve different problems and both matter.

Can a CSRF token be reused across multiple requests in the same session? Some implementations reuse one token per session (simpler, still effective against classic CSRF) while stricter ones rotate a new token per request (harder for an attacker to capture and replay, at the cost of more complexity in handling back-button navigation and multiple open tabs).

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.