Skip to content

关于 CSRF Token 的安全性与下发时机

更新: 5/24/2026 字数: 0 字 时长: 0 分钟

这是两个非常关键的问题,理解清楚才算真正掌握 CSRF Token 的防御原理。

一、CSRF Token 能被黑客获取到吗?

结论先行:在正常的 CSRF 攻击场景下,黑客拿不到 Token;但在某些特定漏洞或不当实现下,Token 可能泄露,防御就会失效

1. 为什么"正常情况下"黑客拿不到?

CSRF Token 的安全性本质上依赖浏览器的同源策略(Same-Origin Policy)

  • 当用户访问正规站点 bank.com 时,Token 被嵌入在 bank.com 的 HTML 页面中。
  • 当用户访问恶意站点 evil.com 时,evil.com 的 JavaScript 无法读取 bank.com 页面的内容——这是浏览器底层强制隔离的。
  • 因此 evil.com 即使能让浏览器自动发请求(携带 Cookie),也没办法在请求里塞入正确的 Token

这就是为什么 Cookie 不能单独防 CSRF,但 Token 可以——Cookie 浏览器会自动带,Token 必须由代码主动读取并放入请求

2. 哪些情况下 Token 会泄露?

如果出现以下漏洞或错误实现,Token 就可能被黑客获取,CSRF 防御直接失守:

泄露途径原理防范方式
XSS 漏洞黑客在正规站点注入 JS,可直接读取页面中的 Token修复 XSS、输入输出过滤、CSP 策略
Token 放在 URL 中通过 Referer 头泄露给第三方站点,浏览器历史、日志也会记录Token 只放在请求体或自定义请求头,不放 URL
HTTP 明文传输中间人可在网络层嗅探到 Token全站强制 HTTPS
Token 写入可被读取的 Cookie(无 HttpOnly)XSS 时可被 document.cookie 读取Cookie 加 HttpOnly;或采用 Double Submit Cookie 时配合其他防护
Token 跨子域共享但子域被攻破攻击者控制子域后可读取 TokenToken 严格限定作用域,按主域隔离
JSONP 接口返回 Token跨域脚本可通过 JSONP 窃取禁止用 JSONP 返回敏感数据
CORS 配置过松Access-Control-Allow-Origin: * 且允许凭证)任意站点可跨域读取响应中的 Token严格白名单,禁止通配符配合 credentials
Token 可预测使用时间戳、自增 ID、弱随机算法生成必须用密码学安全的随机数生成器(如 crypto.randomBytesSecureRandom

关键认知:CSRF Token 防御 CSRF 的前提,是站点不存在 XSS 漏洞。一旦有 XSS,几乎所有 CSRF 防御(包括 SameSite Cookie)都会被绕过。所以业界常说:"XSS 是 CSRF 防御的天花板"。

二、CSRF Token 在什么时机下发?

下发时机的选择,要兼顾安全性用户体验实现复杂度。常见有以下几种策略:

策略 1:用户登录成功时下发(会话级 Token,最常见)

时机:用户登录认证通过后,服务端生成 Token,存入 Session,并通过响应返回给前端。

特点

  • 一次会话期间 Token 不变,前端可缓存复用。
  • 实现简单,性能好。
  • 用户登出或会话过期后 Token 失效,下次登录重新下发。

适用场景:绝大多数业务系统的默认选择。

策略 2:首次访问页面时下发(页面级 Token)

时机:用户请求任意一个需要 CSRF 防护的页面时,服务端在 HTML 中通过 <meta> 标签或隐藏表单字段注入 Token。

html
<meta name="csrf-token" content="随机字符串">
<!-- 或 -->
<input type="hidden" name="_csrf" value="随机字符串">

前端 JS 从 DOM 中读取 Token,加入 AJAX 请求头(如 X-CSRF-Token)。

特点

  • 与后端模板渲染深度结合,典型如 Django、Spring Security、Laravel 的默认实现。
  • 用户未登录时也可下发(用于防注册、登录表单本身被 CSRF)。

适用场景:服务端渲染(SSR)应用、传统 MVC 架构。

策略 3:前端按需请求接口获取(前后端分离场景)

时机:前端启动时(或首次发送敏感请求前)调用专门的接口(如 GET /api/csrf-token)获取 Token,服务端返回并同时写入 Session。

特点

  • 适配 SPA、移动端、前后端完全分离的架构。
  • 前端把 Token 存在内存(不要存 LocalStorage,避免 XSS 风险),后续请求统一带上。

适用场景:React/Vue 等 SPA、API 网关、移动 App。

策略 4:每次敏感操作一次性 Token(One-Time Token)

时机:每次访问关键操作页面(如转账确认页)时,服务端生成一个只能使用一次的 Token,使用后立即作废。

特点

  • 安全性最高,即使 Token 被截获也无法重放。
  • 实现复杂,需处理"用户打开多个标签页"等并发场景。
  • 用户体验略差(页面刷新后旧 Token 失效)。

适用场景:金融交易、支付确认、密码修改等极高敏感操作。

策略 5:Token 定期轮换

时机:在会话有效期内,每隔一段时间(如 30 分钟)或在关键节点(如权限提升后)重新下发 Token。

特点

  • 即使旧 Token 因日志、缓存等渠道泄露,影响窗口有限。
  • 需要前端配合更新逻辑。

适用场景:长会话、高安全等级系统。

三、生产环境推荐实践

场景推荐方案
传统 Web 应用(服务端渲染)登录时下发 + 页面 <meta> 注入 + 会话级 Token
SPA / 前后端分离启动时调接口获取 + 内存存储 + 自定义请求头携带
金融 / 支付类高敏感操作会话级 Token + 关键操作一次性 Token + 二次验证(短信/密码)
微服务 / 无状态架构Double Submit Cookie 模式,无需服务端存储

四、一句话总结

CSRF Token 的安全性建立在"浏览器同源策略 + 站点无 XSS漏洞 + Token 不可预测且不外泄"三个前提之上。 下发时机的核心原则是:在身份确认后尽早下发,存放在攻击者读不到的地方,并随会话生命周期管理——会话级是默认选择,一次性是高敏感场景的加强。