What Is CSRF and How to Protect Your Web Application From It

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.
web security shield

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.

  1. Step 1: Alice logs in to her bank. The server sets a session cookie in her browser.
  2. Step 2: Without logging out, Alice opens another tab and visits a sketchy site, say cute-cat-videos.example.
  3. Step 3: That malicious site contains hidden HTML that auto-submits a form to bank.example.com/transfer.
  4. Step 4: Alice’s browser dutifully attaches her bank session cookie to that request, because that’s how cookies work.
  5. 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.

web security shield

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.
web security shield

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

  1. Set all session cookies with HttpOnly, Secure, and SameSite=Lax (or Strict when possible).
  2. Use a battle-tested CSRF token library for your framework (Django, Laravel, Spring Security, Rails, Express, etc.).
  3. Never use GET requests for state-changing actions.
  4. Validate the Origin or Referer header on sensitive endpoints.
  5. Require re-authentication for high-value operations.
  6. 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.