CSRF, or cross-site request forgery, is a web vulnerability in which a malicious site causes a victim’s browser to send an authenticated request to another application where the victim is already logged in, so the application performs an action the user never intended. In application security, CSRF is a classic example of the confused deputy problem: the server trusts the request because the browser automatically attaches the user’s credentials.
CSRF does not let the attacker read the response. Its power lies in state-changing actions, such as changing an email address, transferring funds, adding an administrator or altering settings, which the attacker triggers blindly but effectively.
How a CSRF attack works
A CSRF attack works because browsers automatically include cookies with requests to a site, regardless of which page initiated the request. If an application relies only on a session cookie to identify the user, it cannot tell whether a request came from its own form or from a hostile page.
The attack follows a short sequence. The victim logs in to the target application and keeps the session open. The victim then visits an attacker-controlled page, which contains an auto-submitting form, an image tag or a script pointing at a sensitive endpoint on the target. The browser sends the request with the session cookie, and the server processes it as legitimate.
Three conditions must hold for CSRF to succeed, and removing any one of them prevents the attack.
| Condition | Why it matters | How to remove it |
|---|---|---|
| A relevant action exists | Something valuable can be changed | Require re-authentication for critical actions |
| Cookie-based session handling | Credentials are attached automatically | Use SameSite cookies or header-based tokens |
| No unpredictable parameters | Attacker can build the full request | Add a secret anti-CSRF token |
Defenses against CSRF
The standard defense is a synchronizer token: a random, unpredictable value tied to the user session and embedded in every state-changing form or request header. The server rejects any request without a valid token, and the attacker cannot read the token because of the same-origin policy.
The table compares the main defense mechanisms and their limitations.
| Defense | Mechanism | Limitation |
|---|---|---|
| Synchronizer token | Server-stored secret checked per request | Requires server-side state |
| Double-submit cookie | Token in cookie must match token in request | Weak if subdomains can set cookies |
| SameSite cookie attribute | Browser withholds cookie on cross-site requests | Lax still allows top-level GET navigation |
| Origin and Referer checks | Server verifies the request source header | Headers may be missing in some cases |
| Custom request header | API requires a header forms cannot set | Relies on correct CORS configuration |
| User re-authentication | Password or MFA for critical actions | Adds friction for users |
Most modern browsers treat cookies without a SameSite attribute as SameSite=Lax by default, which blocks many classic CSRF attacks. This is a valuable defense in depth, not a replacement for tokens, because behavior differs between browsers and Lax still permits some cross-site requests.
CSRF compared with XSS and other web flaws
CSRF exploits the trust a site places in the user’s browser, while XSS exploits the trust a user places in the site. The distinction matters because the defenses are different and one flaw can defeat the protections against the other.
| Issue | Attacker capability | Primary defense |
|---|---|---|
| CSRF | Triggers actions blindly as the user | Anti-CSRF tokens, SameSite cookies |
| XSS | Runs script inside the trusted site | Output encoding, CSP |
| SQL injection | Manipulates database queries | Parameterized queries |
| Clickjacking | Tricks the user into clicking hidden UI | Frame restrictions in CSP |
A single XSS flaw defeats CSRF tokens, because injected script runs on the trusted origin and can read the token from the page. For this reason, broken access control and injection flaws listed in the OWASP Top 10 are usually remediated together with CSRF rather than in isolation.
Where CSRF protection is needed
CSRF protection is needed wherever the browser sends credentials automatically. The risk depends far more on the authentication model than on the programming language or framework.
| Application type | CSRF risk | Reason |
|---|---|---|
| Server-rendered app with session cookies | High | Cookies sent on every request |
| Single-page app using cookie sessions | High | Same automatic cookie behavior |
| API with bearer tokens in headers | Low | Browser does not attach the token automatically |
| Login and logout forms | Moderate | Login CSRF can bind the victim to an attacker account |
| Intranet apps and device admin pages | High | Often lack any token protection |
Most mature web frameworks include built-in CSRF middleware that generates and validates tokens. The safest practice is to keep it enabled globally and to exempt endpoints only with a documented reason.
Common CSRF implementation mistakes
Many CSRF vulnerabilities appear in applications that have a defense but apply it inconsistently. Security testing frequently finds the following gaps.
- Changing state with GET requests, which bypasses form tokens and SameSite Lax protection.
- Validating the token only when present, so an attacker simply omits it.
- Using a token that is not bound to the session, which lets an attacker reuse their own valid token.
- Accepting any content type on JSON endpoints, allowing simple cross-site form posts to reach them.
- Overly permissive CORS with credentials, which can let other origins read responses and tokens.
The simple explanation
Imagine you are signed in to your bank in one browser tab and then open a harmless-looking page in another tab. That page can secretly tell your browser to send a request to the bank, and because you are still signed in, the bank thinks the request came from you.
CSRF is the name for this trick. Websites stop it by adding a secret code to every real form, one that outside pages cannot see or guess. A request without the right code is simply refused.
How it is used in practice
During a security review of an internal ticketing system, a tester notices that the endpoint for changing a user’s notification email accepts a simple form POST with only the session cookie for identification. The tester builds a page with a hidden auto-submitting form and confirms that a logged-in administrator who visits it has their email silently changed, which would allow an attacker to take over the account through password reset.
The development team enables the framework’s CSRF token middleware for all state-changing routes, sets session cookies to SameSite=Lax with the Secure flag, and requires the current password before email changes. A retest confirms that cross-site requests are now rejected with an error and that no state-changing endpoint accepts requests without a valid token.