If you’ve ever wondered what is CSRF and why every web security checklist mentions it, you’re in the right place. Cross-Site Request Forgery (CSRF) is one of the oldest and most misunderstood web vulnerabilities out there, and yet it still shows up in modern applications in 2026. In this beginner-friendly guide, we’ll break down exactly how CSRF works, walk through real vulnerable code, and show you the practical patterns you can apply today to keep your users safe.
What Is CSRF? A Simple Definition
Cross-Site Request Forgery (CSRF, sometimes pronounced “sea-surf” or written as XSRF) is a web security vulnerability that tricks a logged-in user’s browser into sending an unwanted request to a website where they are already authenticated. The attacker doesn’t steal your password. Instead, they abuse the trust your browser already has with a target site.
Think of it as a “confused deputy” attack: your browser is the deputy, holding valid credentials (your session cookie), and the attacker convinces it to do something on your behalf that you never intended.
The Key Ingredients of a CSRF Attack
- A target site that identifies users solely by automatic credentials like session cookies.
- A logged-in victim with an active session on that site.
- A malicious page (or email, or ad) that triggers a request to the target site.
- No mechanism on the target site to verify the request was intentional.

How a CSRF Attack Actually Works (Step by Step)
Let’s demystify the attack flow with a diagram-in-words. Imagine your user, Alice, is logged into her bank at bank.example.com.
- Step 1: Alice logs in to her bank. The server sets a session cookie in her browser.
- Step 2: Without logging out, Alice opens another tab and visits a sketchy site, say
cute-cat-videos.example. - Step 3: That malicious site contains hidden HTML that auto-submits a form to
bank.example.com/transfer. - Step 4: Alice’s browser dutifully attaches her bank session cookie to that request, because that’s how cookies work.
- Step 5: The bank sees a valid session, processes the transfer, and the attacker walks away with Alice’s money.
Alice never clicked anything malicious. She just had two tabs open. That’s the scary part of CSRF.
A Vulnerable Form: What Bad Code Looks Like
Here’s a classic example of a vulnerable money-transfer endpoint. The server only checks the session cookie:
// Vulnerable Express.js endpoint
app.post('/transfer', (req, res) => {
if (!req.session.userId) return res.status(401).send('Login required');
const { to, amount } = req.body;
transferFunds(req.session.userId, to, amount);
res.send('Transfer complete');
});
And here’s the malicious page the attacker hosts:
<!-- Hosted on evil.example -->
<form action="https://bank.example.com/transfer" method="POST" id="f">
<input type="hidden" name="to" value="attacker-account">
<input type="hidden" name="amount" value="5000">
</form>
<script>document.getElementById('f').submit();</script>
As soon as Alice loads that page while logged in, the transfer fires. No clicks needed.

The Two Main Defenses Against CSRF
The good news? CSRF is well-understood and very preventable. There are two layered defenses you should know about in 2026.
1. CSRF Tokens (Synchronizer Token Pattern)
A CSRF token is a unique, unpredictable value generated by your server, embedded in your form, and validated when the form is submitted. Because an attacker on another origin can’t read this token, they can’t forge a valid request.
Here’s a safer version of the form:
<form action="/transfer" method="POST">
<input type="hidden" name="_csrf" value="a1b2c3d4e5f6...">
<input name="to">
<input name="amount">
<button type="submit">Send</button>
</form>
And the server validation:
app.post('/transfer', (req, res) => {
if (req.body._csrf !== req.session.csrfToken) {
return res.status(403).send('Invalid CSRF token');
}
// safe to proceed
});
2. SameSite Cookies
Modern browsers support the SameSite attribute on cookies. It tells the browser whether to send a cookie on cross-site requests. As of 2026, most major browsers default cookies to Lax if you don’t specify, which already blocks the worst CSRF cases.
Set-Cookie: sessionId=abc123; HttpOnly; Secure; SameSite=Strict
| SameSite Value | Behavior | CSRF Protection |
|---|---|---|
| Strict | Never sent on cross-site requests | Strongest |
| Lax | Sent on top-level GET navigation only | Good (default in most browsers) |
| None | Always sent (requires Secure) | None |
Bonus Defenses Worth Knowing
- Double-Submit Cookie Pattern: Send the CSRF token both as a cookie and as a request header. The server checks they match. Useful for stateless APIs.
- Custom Request Headers: For AJAX/fetch APIs, require a header like
X-Requested-With. Browsers won’t let cross-origin forms set custom headers without a CORS preflight. - Re-authentication for sensitive actions: Ask for the password again on money transfers, email changes, or account deletions.
- Origin and Referer header checks: A simple secondary check on state-changing requests.

What About APIs and JWTs?
If your API uses JWT tokens stored in localStorage and sent via an Authorization header, you are not automatically vulnerable to classic CSRF, because browsers don’t auto-attach Authorization headers cross-origin. But the moment you store that JWT in a cookie, you’re back in CSRF territory and need protection.
Quick CSRF Protection Checklist for 2026
- Set all session cookies with
HttpOnly,Secure, andSameSite=Lax(orStrictwhen possible). - Use a battle-tested CSRF token library for your framework (Django, Laravel, Spring Security, Rails, Express, etc.).
- Never use GET requests for state-changing actions.
- Validate the Origin or Referer header on sensitive endpoints.
- Require re-authentication for high-value operations.
- Test your forms with automated tools and manual review.
FAQ: Quick Answers About CSRF
What is CSRF and how does it work?
CSRF is an attack that tricks a logged-in user’s browser into sending an unwanted request to a site where they’re authenticated. It works by exploiting the fact that browsers automatically attach cookies to requests, even when those requests are triggered from another site.
Are CSRF and JWT the same?
No. CSRF is a type of attack, while JWT (JSON Web Token) is a token format used for authentication. JWTs stored in localStorage and sent via headers are generally not vulnerable to classic CSRF, but JWTs stored in cookies are.
What does “CSRF attack detected” mean?
This message usually appears when a server’s CSRF protection middleware notices that a request is missing a valid CSRF token, or the token doesn’t match the one in the user’s session. It often happens after a session timeout or when forms are submitted from cached pages.
What is another name for CSRF?
CSRF is also called XSRF, one-click attack, or session riding.
Is CSRF still relevant in 2026?
Yes. Even with modern SameSite=Lax defaults, edge cases exist (subdomain attacks, misconfigured cookies, legacy browsers, mobile webviews). Defense in depth with CSRF tokens remains best practice.
Wrapping Up
Now that you know what CSRF is, how attackers exploit it, and how to defend against it, you’re already ahead of most developers. Combine CSRF tokens with SameSite cookies, validate Origin headers on sensitive endpoints, and require re-authentication for high-stakes actions. With these layered defenses in place, your users (and your reputation) stay safe.
Security isn’t a one-time fix, it’s a habit. Audit your forms today and make sure CSRF doesn’t become the vulnerability that ruins your week.

