EXERCISE 1 — A manual test plan for CSRF on a state-changing endpoint ===================================================================== (Test only your OWN app, or an authorized target.) STEP 1 -- Capture a legitimate request. Log in normally; perform the action (e.g. change email). In DevTools -> Network (or Burp proxy), capture the full state-changing request: method, URL, headers, cookies, body. -> You now have a known-good request to manipulate. STEP 2 -- Identify the auth mechanism. Look at how it authenticates: - Session/JWT COOKIE -> CSRF is relevant, continue. - Authorization: Bearer header (added by JS) -> not classic CSRF; stop (focus on XSS instead). (Chapter 9.) STEP 3 -- Remove the CSRF token / custom header and REPLAY. Re-send the captured request but DELETE the anti-CSRF token (hidden field or X-CSRF-Token header) and any custom header, KEEPING the session cookie. RESULT INDICATING VULNERABILITY: - The action still SUCCEEDS (200/redirect, state changed) -> the token is NOT being validated server-side. VULNERABLE. - The action is REJECTED (403) -> token validation is enforced. Good; continue to step 4/5. STEP 4 -- Forged cross-origin page test. Build an auto-submitting form (Chapter 3) on a DIFFERENT origin pointing at the endpoint with attacker-chosen values. Load it while logged in. RESULT INDICATING VULNERABILITY: - The action fires (cookie auto-attached, no token needed) -> VULNERABLE. - Browser doesn't send the cookie (SameSite) or server rejects (missing token) -> defended. Also try a state-changing GET via if any GET mutates state. - Fires -> VULNERABLE (state change on GET). STEP 5 -- Token strength / validation quality. Probe the token check itself: - Submit an EMPTY token -> accepted? VULNERABLE (absent treated as valid). - Submit ANOTHER user's / an old (pre-rotation) token -> accepted? VULNERABLE (not bound to session / not rotated). - Predictable token (looks sequential / low-entropy)? Weak generation. RESULT INDICATING VULNERABILITY: any of the above accepted. PASS CRITERIA (endpoint is adequately protected): - Removing the token -> rejected (step 3). - Cross-origin forged page -> action does NOT fire (step 4). - No state change on GET (step 4). - Empty / foreign / stale tokens -> rejected; token is high-entropy (step 5). TOOLING: Burp Suite "Generate CSRF PoC" auto-builds the step-4 forged page; OWASP ZAP flags missing/unvalidated tokens. But the manual step-3 replay is the single most revealing test.