csrf-cross-site-request-forgery
CSRF testing playbook. Use when reviewing state-changing web flows, anti-CSRF defenses, SameSite behavior, JSON CSRF, login CSRF, and OAuth state handling.
By yaklang · 3,063 installs
npx skills add yaklang/hack-skills --skill csrf-cross-site-request-forgery
Source repository · Upstream listing
SKILL: CSRF — Cross Site Request Forgery — Expert Attack Playbook
AI LOAD INSTRUCTION : Expert CSRF techniques. Covers modern bypass vectors (SameSite gaps, custom header flaws, tokenless bypass patterns), JSON CSRF, multipart CSRF, chaining with XSS. Base models often present only basic CSRF without covering SameSite edge cases and common broken token implementations.
0. RELATED ROUTING
Also load:
[cors cross origin misconfiguration](../cors cross origin misconfiguration/SKILL.md) when JSON endpoints become readable cross origin
[oauth oidc misconfiguration](../oauth oidc misconfiguration/SKILL.md) when login, account linking, or callback binding relies on OAuth state
1. CORE CONCEPT
CSRF exploits a victim's active session to perform state changing requests from the attacker's origin .
Required conditions :
1. Victim is authenticated (active session cookie)
2. Server identifies session via cookie only (no secondary check)
3. Attacker can predict/construct the valid request
4. Cookie is sent cross origin (SameSite=None or legacy behavior)
2. FINDING CSRF TARGETS
High value state changing endpoints :
3. TOKEN BYPASS TECHNIQUES
No Token Present
Simplest case — form simply lacks CSRF token. Check if POST /change email has any token. If not → trivially exploitable.
Token Not Validated (most common finding!)
Token exists in request but is never verified server side:
Token Tied to Session but Not to User
Token in Cookie Only
When server sets CSRF token as cookie and expects it back in a header/form:
Static or Predictable Token
Double Submit Cookie Pattern (broken if subdomain trusted)
4. SAMESITE BYPASS SCENARIOS
SameSite=Lax (modern browser default): cookies sent for top level GET navigation, NOT for cross site iframe/form POST.
Bypass SameSite=Lax via GET method :
Bypass via subdomain XSS (SameSite Lax/Strict) :
SameSite=None (legacy or explicit): cookies sent everywhere → classic CSRF applies.
Cookie issued recently? Lax exemption:
Chrome has a 2 minute exception where Lax cookies ARE sent on cross site POSTs if the cookie was just set (for OAuth flows). Race window: set cookie, immediately trigger CSRF within 2 minutes.
5. CSRF PROOF OF CONCEPT TEMPLATES
Simple Form POST
Auto click Submit
CSRF via GET (with img tag)
CSRF with Custom Header (XMLHttpRequest — same origin only, defeats naive defenses)
If API requires custom header like X CSRF Token but also accepts JSON with wildcard CORS — custom headers don't protect if CORS misconfigured:
6. JSON CSRF
When endpoint accepts Content Type: application/json — fetch() with CORS credentials:
Requires : Access Control Allow Origin: https://attacker.com AND Access Control Allow Credentials: true
If server only accepts application/json but no fetch CORS:
Can't do proper JSON CSRF from HTML form (forms can only send application/x www form urlencoded , multipart/form data , text/plain ).
Trick — Content Type Downgrade : If server processes text/plain body as JSON:
Resulting body: {"email":"attacker@evil.com","ignore":"="}
7. MULTIPART CSRF
When changing Content Type from application/json to multipart/form data and request still works:
8. CSRF + XSS COMBINATION (CSRF Token Bypass)
When CSRF protection is otherwise solid, XSS enables CSRF bypass:
9. OAUTH CSRF (STATE PARAMETER MISSING)
OAuth flow without state parameter → CSRF on the OAuth authorization:
Attack :
1. Attacker initiates OAuth flow, gets authorization code
2. Before exchanging code, stops the flow (captures the redirect URL with code)
3. Sends victim the crafted URL: https://target.com/oauth/callback?code=ATTACKER CODE
4. Victim's browser exchanges the attacker's code → victim's account linked to attacker's OAuth provider
Impact : Attacker can log in as victim.
10. CSRF TESTING CHECKLIST
11. JSON CSRF TECHNIQUES
Method 1: text/plain Disguise
Method 2: XHR with Credentials
Method 3: fetch() API
12. MULTIPART CSRF & CLIENT SIDE PATH TRAVERSAL
Multipart File Upload CSRF
Client Side Path Traversal to CSRF (CSPT2CSRF)
Aspect Traditional CSRF CSPT2CSRF
Origin Attacker's site Same origin JavaScript
Token bypass Needs token forgery No token needed (same origin)
SameSite Blocked by SameSite=Strict Bypasses SameSite (same site!)
Detection Standard CSRF checks Requires input validation on path segments
13. SAMESITE=LAX ADVANCED BYPASS TECHNIQUES
13.1 Top level navigation via window.open() (2 minute window)
Chrome's Lax+POST exception: cookies with SameSite=Lax are sent on cross site POST requests if the cookie was set within the last 2 minutes (exists for OAuth flows).
13.2 302 redirect chain from attacker site
Lax cookies are sent on top level GET navigations. A redirect chain converts GET into action:
13.3 Method override: POST disguised as GET
Many frameworks support method override via method parameter:
Headers that trigger method override:
SameSite=Lax allows the GET → framework processes it as POST/DELETE via override → CSRF on "POST only" endpoints.
14. ADVANCED JSON CSRF TECHNIQUES
14.1 Flash based Content Type manipulation (legacy)
Flash (pre 2021) could send arbitrary Content Type headers cross origin without preflight:
Legacy but still relevant for older internal applications.
14.2 fetch() no cors mode limitations and workarounds
fetch() in no cors mode can send simple requests but cannot set Content Type: application/json (triggers preflight) or read the response.
Workaround — if the server accepts text/plain body and parses it as JSON:
14.3 Encoding JSON as form urlencoded
Some backends accept both content types:
If the server processes role=admin&user id=123 the same as {"role":"admin","user id":123} → CSRF via plain HTML form without CORS preflight.
15. CSRF + CORS MISCONFIGURATION CHAINS
Reflected Origin + Credentials
Subdomain XSS → CORS → CSRF
If .target.com is in the CORS allowlist and an XSS exists on any subdomain:
1. Exploit XSS on blog.target.com
2. From XSS context, fetch API at api.target.com (CORS allows subdomain)
3. Read CSRF token from response
4. Submit state changing request with valid token
16. CSRF TOKEN FIXATION (PRE SESSION TOKENS)
If CSRF tokens are issued before authentication and remain valid after login:
Test procedure
17. CLICKJACKING AS CSRF BYPASS
When CSRF protections are solid but X Frame Options / frame ancestors is missing:
Attack flow
PoC template
Defense check