Skip to main content
Offensive360
Home / Knowledge Base / Cross-Site Request Forgery (CSRF)
High CWE-352 A01:2021 Broken Access Control

Cross-Site Request Forgery (CSRF)

CSRF tricks authenticated users into unknowingly submitting malicious requests. Learn how CSRF tokens, SameSite cookies, and origin validation prevent these attacks.

Affects: C#JavaJavaScriptPHPPythonRuby

What is Cross-Site Request Forgery?

Cross-Site Request Forgery (CSRF) is an attack that forces an authenticated user to unknowingly execute unwanted actions on a web application. The attacker crafts a malicious page or email that causes the victim’s browser to send a forged request — carrying the victim’s session cookies — to a trusted site.

Unlike Cross-Site Scripting (XSS), which exploits the user’s trust in a site, CSRF exploits the site’s trust in the user’s browser. If the victim is logged in to a banking application and visits an attacker-controlled page, that page can silently trigger a funds transfer on their behalf.

CSRF affects any application that relies solely on cookies or HTTP authentication to authorize requests, and where state-changing operations can be triggered via GET or unauthenticated POST.

How exploitation works

The attacker hosts a page containing a hidden form that targets the victim’s authenticated session:

<!-- Attacker's page — victim visits this link -->
<form action="https://bank.example.com/transfer" method="POST" id="csrf">
  <input type="hidden" name="to" value="attacker_account" />
  <input type="hidden" name="amount" value="10000" />
</form>
<script>document.getElementById('csrf').submit();</script>

When the victim’s browser submits this form, it automatically includes the session cookie for bank.example.com, making the request appear legitimate to the server.

Vulnerable code examples

ASP.NET Core — missing CSRF validation

// VULNERABLE: No [ValidateAntiForgeryToken] attribute
[HttpPost]
public IActionResult ChangeEmail(string newEmail)
{
    var userId = User.GetUserId();
    _userService.UpdateEmail(userId, newEmail);
    return Ok();
}

Java Spring — CSRF disabled

// VULNERABLE: CSRF protection explicitly disabled
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable(); // Never disable in production
    }
}

Secure code examples

ASP.NET Core — CSRF token validation

// SECURE: Enforce anti-forgery token on all state-changing endpoints
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult ChangeEmail(string newEmail)
{
    var userId = User.GetUserId();
    _userService.UpdateEmail(userId, newEmail);
    return Ok();
}

Python / Django — built-in CSRF middleware

# SECURE: Django's CsrfViewMiddleware is enabled by default.
# Include {% csrf_token %} in every form.
# For AJAX, read the csrftoken cookie and send as X-CSRFToken header.

# settings.py
MIDDLEWARE = [
    'django.middleware.csrf.CsrfViewMiddleware',  # Must be present
    ...
]

What Offensive360 detects

  • Missing CSRF token validation — State-changing endpoints (POST, PUT, PATCH, DELETE) lacking framework-level CSRF protection
  • Explicitly disabled CSRF middleware — Calls to csrf().disable(), @csrf_exempt, or equivalent that remove built-in protections
  • GET-based state changes — Endpoints that perform writes triggered by HTTP GET requests
  • Missing SameSite cookie attribute — Session cookies issued without SameSite=Lax or Strict
  • Insecure API token usage — Endpoints that accept authentication only via cookies without a secondary CSRF check

Remediation guidance

  1. Use synchronizer token pattern — Generate a unique, unpredictable token per session and validate it on every state-changing request.

  2. Set SameSite=Lax or Strict on session cookies — Modern browsers block cross-origin cookie sending for requests that match SameSite restrictions. This is a strong, low-friction defense.

  3. Validate the Origin/Referer header — Reject requests where the Origin or Referer does not match your application’s domain.

  4. Use framework defaults — ASP.NET Core, Django, Rails, and Spring all include CSRF protection. Enable and configure it rather than building custom solutions.

  5. Prefer custom request headers for APIs — AJAX requests can include a custom header (e.g., X-Requested-With) that browsers cannot send cross-origin without CORS approval.

References

By Offensive360 Security Research Reviewed: March 2026

Detect Cross-Site Request Forgery (CSRF) automatically

Run Offensive360 SAST on your codebase to find this and 100+ other vulnerabilities.