Skip to main content
SecScannerSecScanner
Security ChecksFree ToolsPricingBlog
Get Started
Sign InGet Started
← Back to Blog
GeneralFebruary 4, 202610 min read

CSRF Attacks Explained: Prevent Cross-Site Request Forgery

CSRF tricks authenticated users into performing unintended actions. Learn how CSRF attacks work and modern defenses with tokens and SameSite cookies.

By SecScanner Team
CSRF Attacks Explained: Prevent Cross-Site Request Forgery

Cross-Site Request Forgery (CSRF) is an attack that forces authenticated users to perform actions they didn't intend. If a user is logged into their bank and visits a malicious page, that page can submit a hidden form that transfers money — using the user's existing session. CSRF exploits the trust a website has in the user's browser.

How CSRF Attacks Work

The Attack Scenario

  1. The victim is authenticated on bank.com (has a valid session cookie)
  2. The victim visits evil.com while still logged in
  3. evil.com contains a hidden form that posts to bank.com/transfer
  4. The browser automatically includes the bank.com session cookie with the request
  5. The bank processes the transfer because the request appears legitimate

CSRF Attack Example

<!-- On evil.com - auto-submitting form -->
<form action="https://bank.com/transfer" method="POST" id="csrf-form">
  <input type="hidden" name="to" value="attacker-account">
  <input type="hidden" name="amount" value="10000">
</form>
<script>document.getElementById('csrf-form').submit();</script>

GET-Based CSRF

If state-changing operations use GET requests, CSRF is even simpler:

<!-- A simple image tag triggers the attack -->
<img src="https://bank.com/transfer?to=attacker&amount=10000">

Modern CSRF Defense Strategies

1. SameSite Cookie Attribute (Primary Defense)

The SameSite cookie attribute is the most effective modern CSRF defense:

Set-Cookie: session=abc123; SameSite=Lax; Secure; HttpOnly
  • SameSite=Strict: Cookie is never sent on cross-site requests. Maximum security but breaks legitimate cross-site navigation (e.g., clicking a link to your site from email).
  • SameSite=Lax: Cookie is sent on top-level navigations (clicking links) but blocked on cross-site POST requests, form submissions, and AJAX calls. Best balance of security and usability.
  • SameSite=None: Cookie is always sent (requires Secure flag). No CSRF protection — only use when cross-site access is intentional.

2. CSRF Tokens (Synchronizer Token Pattern)

Generate a unique, unpredictable token for each user session and require it on all state-changing requests:

<form action="/transfer" method="POST">
  <input type="hidden" name="csrf_token" value="UNIQUE_RANDOM_TOKEN">
  <!-- other form fields -->
</form>

The server validates the token on every POST request. Since the attacker's page cannot read the token (blocked by Same-Origin Policy), they cannot forge a valid request.

3. Double Submit Cookie Pattern

Send the CSRF token as both a cookie and a request parameter. The server verifies they match:

// Set CSRF cookie
Set-Cookie: csrf=TOKEN; SameSite=Strict; Secure

// Include in request header
X-CSRF-Token: TOKEN

4. Custom Request Headers

Require a custom header on state-changing requests. Browsers don't allow cross-origin requests with custom headers without CORS preflight:

// Client-side
fetch('/api/transfer', {
  method: 'POST',
  headers: { 'X-Requested-With': 'XMLHttpRequest' },
  body: data
});

// Server-side: reject requests without the header

Framework-Specific Implementation

Express.js with csurf

const csrf = require('csurf');
const csrfProtection = csrf({ cookie: true });

app.get('/form', csrfProtection, (req, res) => {
  res.render('form', { csrfToken: req.csrfToken() });
});

app.post('/submit', csrfProtection, (req, res) => {
  // Token is automatically validated
  res.send('Success');
});

Django

Django includes CSRF protection by default. Include the template tag in forms:

<form method="POST">
  {% csrf_token %}
  <!-- form fields -->
</form>

Next.js API Routes

For Next.js applications, combine SameSite cookies with custom headers:

// Verify the Origin header matches your domain
export async function POST(request) {
  const origin = request.headers.get('origin');
  if (origin !== 'https://yourdomain.com') {
    return new Response('Forbidden', { status: 403 });
  }
  // Process the request
}

Common CSRF Mistakes

  • Using GET for state changes: GET requests should never modify data. Use POST, PUT, or DELETE.
  • CSRF token in URL: Tokens in query strings leak via Referer headers and browser history.
  • Per-session tokens only: Use per-request or per-form tokens for stronger protection.
  • Not validating on all endpoints: Every state-changing endpoint needs CSRF protection.
  • Relying on SameSite=None: This provides zero CSRF protection.

CSRF Prevention Checklist

  • Set SameSite=Lax on all session cookies (minimum defense)
  • Implement CSRF tokens for all state-changing forms
  • Never use GET requests for operations that modify data
  • Validate Origin and Referer headers on the server
  • Use framework-provided CSRF protection
  • Test CSRF defenses with different browsers
  • Run a SecScanner scan to verify Anti-CSRF token implementation

CSRF attacks exploit the most fundamental trust model of the web — that browsers automatically send credentials with every request. Modern defenses like SameSite cookies have dramatically reduced CSRF risk, but defense in depth with tokens and header validation remains best practice for high-security applications.

Related Articles

Headers

Cookie Security: HttpOnly, Secure, SameSite and Beyond

9 min read

Headers

CORS Security: The Complete Guide to Cross-Origin Resource Sharing

11 min read

General

Open Redirect Vulnerabilities: How Attackers Abuse URL Redirects

9 min read

Check Your Website Security

Want to see how your website measures up? Run a free security scan with SecScanner to identify vulnerabilities and get actionable remediation guidance.

Scan Your Website Free
All Security ChecksCookie Security CheckerVulnerability Scanner

On This Page

Product

  • Security Checks
  • Free Tools
  • SSL Checker
  • Vulnerability Scanner
  • Email Security
  • Pricing
  • Compliance
  • Security Reports

Popular Checks

  • CSP Check
  • HSTS Check
  • TLS Version Check
  • SSL Expiry Check
  • SPF/DKIM/DMARC Check
  • Cookie Security Check
  • JS Vulnerability Scan
  • OCSP Stapling Check

Resources

  • Blog
  • Glossary
  • Contact

Legal

  • Terms of Use
  • Privacy Policy
  • Refund Policy
  • Cookie Policy

© 2025-2026 SecScanner. All rights reserved.