Missing CSRF Protection
debt(d5/e3/b3/t7)
Closest to 'specialist tool catches it' (d5), because the detection_hints list semgrep and owasp-zap — both specialist SAST/DAST tools. A standard linter won't flag a missing middleware check; you need a dedicated security scanner or manual review to catch missing CSRF protection across routes.
Closest to 'simple parameterised fix' (e3), because the quick_fix is 'Add CSRF middleware to all state-changing routes and verify the token on every POST/PUT/PATCH/DELETE request.' This is more than a one-line patch (it touches every state-changing route), but it is a repeatable pattern within one component/framework layer rather than a cross-cutting architectural refactor.
Closest to 'localised tax' (b3), because applies_to is scoped to web contexts only and the fix is contained to route/middleware configuration. Once CSRF middleware is correctly wired in, it doesn't impose ongoing weight on most of the codebase; the burden is real but localised to the routing/middleware layer.
Closest to 'serious trap' (t7), because the misconception field documents a genuine expert-level wrong belief: developers familiar with SameSite cookies believe they have replaced CSRF tokens, but SameSite=Lax still allows top-level navigation POSTs in some browsers. Additionally, common_mistakes include generating the token but never validating it (silent no-op) and only protecting forms but not AJAX endpoints — these are traps that contradict the intuition of developers who know a related concept (cookie security) but don't know the edge cases.
Also Known As
TL;DR
Explanation
Cross-Site Request Forgery exploits the browser's automatic cookie sending — if a victim is logged in and visits a malicious page, that page can silently POST to your application using the victim's session. The fix is a synchronised token: generate a unique random value per session, embed it in every form as a hidden field, and validate it on every state-changing request. The token must be unpredictable, tied to the session, and verified server-side.
Common Misconception
Why It Matters
Common Mistakes
- Checking Referer header instead of a token — Referer can be stripped by proxies and is not reliable.
- Using the same CSRF token across multiple sessions — tokens must be unique per session.
- Only protecting forms, not AJAX endpoints — JSON AJAX requests from a malicious site can also trigger CSRF.
- Generating the token but never validating it server-side — silent no-op.
Code Examples
// No CSRF token — any site can forge this request:
<form method="POST" action="/change-password">
<input name="password" type="password">
<button type="submit">Change Password</button>
</form>
// PHP processes it without validation:
$_POST['password']; // Accepted from anywhere
// Generate token once per session:
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
// Embed in form:
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
// Validate on every POST:
if (!hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'] ?? '')) {
http_response_code(403);
exit('Invalid CSRF token');
}