Complete CSRF Prevention Cheatsheet: Secure Your Web Applications

Introduction: Understanding CSRF

Cross-Site Request Forgery (CSRF) is a type of security vulnerability where attackers trick authenticated users into unknowingly executing unwanted actions on websites they’re logged into. CSRF attacks exploit the trust that a website has in a user’s browser by forcing the victim’s browser to send forged HTTP requests to a target site.

Why CSRF Prevention Matters:

  • Protects users from performing unintended actions
  • Prevents unauthorized transactions, data modification, or account takeovers
  • Required for compliance with security standards like OWASP Top 10
  • Maintains trust in your application and brand reputation

Core CSRF Concepts

How CSRF Attacks Work

  1. User authenticates with a legitimate website (e.g., banking site)
  2. Authentication creates a session cookie stored in the user’s browser
  3. Without logging out, user visits a malicious website
  4. The malicious site contains code that submits a request to the legitimate site
  5. The browser automatically includes the session cookie with the request
  6. The legitimate site processes the request as authentic since it contains valid credentials

Key Principles of CSRF Prevention

PrincipleDescription
Defense in DepthImplement multiple layers of protection rather than a single solution
Verification of IntentEnsure requests come from legitimate UI interactions
Same-Origin PolicyBrowsers restrict how documents/scripts from one origin interact with resources from another
Proper Session ManagementSessions should expire appropriately and require re-authentication for sensitive actions

CSRF Prevention Methods

1. Synchronizer (CSRF) Tokens

The most common and effective defense against CSRF attacks.

Implementation Steps:

  1. Generate a unique, unpredictable token for each user session
  2. Include this token as a hidden field in all forms
  3. Send the token in custom HTTP headers for AJAX requests
  4. Validate the token on the server for every state-changing request
<form action="/transfer" method="post">
    <input type="hidden" name="csrf_token" value="random_token_value">
    <!-- Form fields -->
    <button type="submit">Submit</button>
</form>
// AJAX request with CSRF token
fetch('/api/data', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').content
    },
    body: JSON.stringify(data)
});

2. Same-Site Cookies

Implementation:

Set-Cookie: sessionid=abc123; SameSite=Strict; Secure; HttpOnly

SameSite Values:

ValueBehaviorUse Case
StrictCookies only sent in first-party contextHighest security; may impact legitimate cross-site functionality
LaxCookies sent with GET requests in top-level navigationsGood balance of security and usability (default in modern browsers)
NoneCookies sent in all contexts (requires Secure flag)Use only when cross-site functionality is absolutely necessary

3. Custom Request Headers

For AJAX requests, custom headers like X-Requested-With: XMLHttpRequest provide protection because browsers don’t allow custom headers in cross-site requests without CORS.

4. Double Submit Cookie

  1. Set a CSRF token as a cookie
  2. Include the same token as a request parameter or header
  3. Verify that both values match on the server

5. Re-Authentication for Sensitive Actions

Require password re-entry or two-factor authentication for critical operations like:

  • Password changes
  • Email changes
  • Financial transactions
  • Account deletion

CSRF Prevention by Framework

FrameworkBuilt-in ProtectionImplementation
SpringCSRF tokens<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
DjangoCSRF middleware{% csrf_token %} in forms
LaravelCSRF middleware@csrf directive in forms
Express.jscsurf middleware<input type="hidden" name="_csrf" value="<%= csrfToken %>">
ASP.NETAntiForgeryToken@Html.AntiForgeryToken() in forms
Ruby on RailsCSRF protection<%= csrf_meta_tags %> in layout
AngularHttpClientXsrfModuleAutomatically handles CSRF tokens
ReactNo built-in (use custom)Manually include token from cookies/state

Common CSRF Challenges and Solutions

Single Page Applications (SPAs)

Challenge: Traditional form-based CSRF protection doesn’t work well with API-based SPAs.

Solution:

  • Use custom HTTP headers for all state-changing requests
  • Implement token-based authentication (JWT) with proper storage
  • Utilize CSRF tokens in request headers or in the Authorization header

Third-Party Integrations

Challenge: Third-party services may not support your CSRF protection.

Solution:

  • Use separate, dedicated endpoints for third-party integrations
  • Implement additional authorization checks for these endpoints
  • Consider using signed requests with API keys instead of cookies

GET Requests for State Changes

Challenge: GET requests should never change state, but sometimes they do.

Solution:

  • Always use POST/PUT/DELETE for state-changing operations
  • Apply CSRF protection to all non-GET methods
  • Refactor existing GET endpoints that change state

Testing for CSRF Vulnerabilities

Manual Testing Checklist

  • [ ] Identify all state-changing functionality
  • [ ] Check if CSRF tokens are implemented
  • [ ] Verify token validation on the server
  • [ ] Test token expiration and rotation
  • [ ] Confirm tokens are unpredictable
  • [ ] Verify proper SameSite cookie attributes

Automated Testing Tools

  • OWASP ZAP
  • Burp Suite Professional
  • Acunetix
  • Netsparker
  • Custom scripts with tools like Selenium

CSRF Prevention Implementation Checklist

  • [ ] Implement CSRF tokens for all forms and AJAX requests
  • [ ] Set SameSite=Lax or Strict for all cookies
  • [ ] Use HttpOnly and Secure flags for sensitive cookies
  • [ ] Require re-authentication for sensitive operations
  • [ ] Implement proper token validation on the server
  • [ ] Apply CSRF protection to all state-changing operations
  • [ ] Add referrer and origin validation as an additional layer
  • [ ] Test CSRF protection with both automated tools and manual testing
  • [ ] Document CSRF protection mechanisms for developers

Best Practices

  • Never use GET requests for state-changing operations
  • Generate cryptographically strong, random tokens
  • Tie CSRF tokens to the user’s session
  • Implement proper error handling for invalid or missing tokens
  • Rotate tokens after successful form submissions
  • Use HTTPS for all traffic to prevent token leakage
  • Don’t store CSRF tokens in localStorage (vulnerable to XSS)
  • Apply defense in depth with multiple protection mechanisms

Resources for Further Learning

Official Documentation

Security Tools

Books and Courses

  • “Web Application Security: A Beginner’s Guide” by Bryan Sullivan
  • “The Tangled Web: A Guide to Securing Modern Web Applications” by Michal Zalewski
  • “Web Security Academy” by PortSwigger
  • SANS SEC542: Web App Penetration Testing and Ethical Hacking
Scroll to Top