iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Code Review

A CSRF code review focuses on every state-changing request handler: does it require a token, a custom header, or mTLS? Are GET requests purely read-only? Are SameSite cookies set? Are CORS rules tight? This checklist turns it into a 15-minute pass per PR so CSRF bugs are caught before merge, not in a pen test.

CSRF review checklist with reviewable diffs

EXAMPLE
# CSRF code-review checklist (paste into the PR description)

## 1) Every state-changing route is POST/PUT/PATCH/DELETE
- [ ] No GET handler mutates state. Search for \\`Route::get\\` followed by writes.

## 2) Anti-CSRF token enforced on writes
- [ ] Laravel: route uses the 'web' middleware group (VerifyCsrfToken).
- [ ] Forms include \\`@csrf\\` (Blade) or send X-XSRF-TOKEN header.
- [ ] Same-origin XHR/fetch sends the cookie value back as a header.

## 3) Cookies are SameSite-protected
- [ ] config/session.php: 'same_site' => 'lax' (or 'strict' for high-risk apps).
- [ ] 'secure' => true in production.

## 4) CORS is opted in, not opt-out
- [ ] config/cors.php: 'paths' lists only the routes that need CORS.
- [ ] 'allowed_origins' is an explicit list, no '*'.
- [ ] 'supports_credentials' => true ONLY where required, and origin is exact.

## 5) Auth endpoints reject GET
- [ ] Login, password reset, OAuth callback only accept POST.

## 6) JSON APIs without cookies: custom required header
- [ ] Bearer-token APIs add a custom header (Authorization), so simple forms
      cannot trigger a CSRF (browsers reject custom headers cross-origin).

# Example diff: harden a state-changing route

# BEFORE — bug
Route::get('/account/email', function (Request $request) {
    $user = auth()->user();
    $user->email = $request->query('to');     // ❌ GET that mutates
    $user->save();
    return 'ok';
});

# AFTER — fix
Route::post('/account/email', function (Request $request) {
    $data = $request->validate(['to' => ['required','email']]);
    $request->user()->update($data);          // ✅ POST + token + validation
    return response()->noContent();
})->middleware(['auth', 'verified']);

# Programmatic checks the reviewer can run
# 1) Find GETs that look mutating
git grep -n -E "Route::get\\(.*function" | grep -i -E 'update|delete|set|save|destroy'

# 2) Find disabled CSRF middleware
git grep -n 'VerifyCsrfToken' | grep -i 'except'

# 3) Confirm cookie config
grep -n 'same_site\|secure' config/session.php

Why it matters

A CSRF review takes 15 minutes per PR and catches a class of bugs that automated scanners often miss. The single highest-value check: search the diff for any new GET route that writes — those are the easy attacker wins.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// Check every state-changing endpoint for:
// - Method (must NOT be GET)
// - CSRF token / custom-header check
// - SameSite cookie config
// - Origin/Referer validation for SSR forms
Try it Yourself »

Discussion

Loading…