← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Cross-Site Request Forgery (CSRF)

Security CWE-352 OWASP A1:2021 CVSS 6.5 PHP 5.0+ Intermediate
debt(d5/e3/b5/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches' (d5). The term's detection_hints specify semgrep as the tool and note automated detection is 'no' — meaning standard linters won't catch it. SAST tools like semgrep can detect missing CSRF token verification patterns, but it requires deliberate configuration and isn't caught by default PHP tooling.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix specifies adding SameSite=Lax to session cookie and including a per-session CSRF token in forms. This is more than a one-line patch (requires middleware configuration, form updates, and potentially token validation logic) but is a well-understood pattern that doesn't require architectural changes — typically a few files in one component.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). CSRF protection must be applied consistently across all state-changing endpoints in the web context. The applies_to shows it affects all web PHP contexts. Every new form and state-changing route requires the developer to remember to include tokens, creating an ongoing tax. It shapes how you build forms but doesn't define the entire system architecture.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception field explicitly states developers believe 'HTTPS prevents CSRF' — a documented gotcha that most developers eventually learn is false. The common_mistakes list shows several additional traps (protecting only POST, presence-check-only validation, static tokens), but these are learnable through standard security training rather than being catastrophically counterintuitive.

About DEBT scoring →

Also Known As

Cross-Site Request Forgery XSRF sea-surf

TL;DR

A forged request tricks an authenticated user's browser into performing an unintended action on a site they're logged into.

Explanation

CSRF exploits the browser's automatic inclusion of session cookies. An attacker hosts a page with a hidden form or image tag that sends a state-changing request to the target site. The victim's browser attaches their valid session cookie, so the server treats it as legitimate. Mitigation requires a per-session, per-form unpredictable token that the attacker cannot know — validated server-side with a constant-time comparison.

How It's Exploited

<!-- Evil site — tricks logged-in victim into clicking -->
<img src="https://yourbank.com/transfer?to=attacker&amount=9999">

Diagram

sequenceDiagram
    participant V as Victim Browser
    participant L as "Legit Bank<br/>bank.com"
    participant A as "Attacker Site<br/>evil.com"
    V->>L: Login to bank.com
    L-->>V: Session cookie set
    A->>V: Serve malicious page with hidden form
    V->>L: "POST /transfer (auto-submit)<br/>Cookie sent automatically!"
    L-->>L: Transfer executed - no CSRF token checked
    Note over L: "Fix: require CSRF token in POST body<br/>that attacker cannot read"

Common Misconception

HTTPS prevents CSRF. CSRF exploits the browser's automatic cookie sending and works over HTTPS just as well as HTTP. SameSite cookies and CSRF tokens are the actual mitigations.

Why It Matters

CSRF tricks authenticated users into submitting requests they never intended — transferring money, changing passwords, or deleting accounts. A missing CSRF token on a state-changing endpoint is a critical vulnerability regardless of how complex the authentication is.

Common Mistakes

  • Protecting POST routes but forgetting PUT, PATCH, and DELETE — all state-changing methods need tokens.
  • Validating the token exists but not validating it matches the session — presence check alone is useless.
  • Disabling CSRF middleware globally in API routes and forgetting the app also serves browser clients.
  • Using a static, never-rotating token — tokens must be per-session and ideally per-request.

Code Examples

✗ Vulnerable
// No CSRF token — any site can submit this form on behalf of the user
Route::post('/account/delete', [AccountController::class, 'destroy']);
✓ Fixed
// Laravel — CSRF middleware applied globally, @csrf in every form
<form method="POST" action="/account/delete">
    @csrf
    <button>Delete account</button>
</form>

// For APIs: use SameSite=Strict cookies + verify Origin header
if ($_SERVER['HTTP_ORIGIN'] !== 'https://yourapp.com') {
    http_response_code(403); exit;
}

Added 13 Mar 2026
Edited 19 Apr 2026
Views 97
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 3 pings W 5 pings T 7 pings F 4 pings S 7 pings S 9 pings M 1 ping T 2 pings W 1 ping T 1 ping F 2 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 1 ping S 1 ping S 2 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 36 Perplexity 14 Amazonbot 10 Ahrefs 5 SEMrush 5 PetalBot 4 Unknown AI 2 Google 2 Claude 2 ChatGPT 1 Meta AI 1 Bing 1
crawler 81 crawler_json 2
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Medium
⚡ Quick Fix
Add SameSite=Lax to session cookie and include a per-session CSRF token in every state-changing form
📦 Applies To
PHP 5.0+ web
🔗 Prerequisites
🔍 Detection Hints
POST/PUT/DELETE handler with no CSRF token verification or missing SameSite cookie
Auto-detectable: ✗ No semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✗ Manual fix Fix: Medium Context: File Tests: Update
CWE-352


✓ schema.org compliant