首页/安全/漏洞与攻击面速查/CSRF Token 实现要点
Web 漏洞原理与防护55 条

CSRF Token 实现要点

CSRF Token 是服务端生成、与用户会话关联的随机值:表单或请求头回传、服务端比对;实现要防预测、防复用,并避免把令牌泄露到 URL 与日志中。

漏洞与攻击面速查安全更新于 2026-10-13

CSRF Token 是什么

CSRF Token 是服务端生成、与用户会话绑定的随机值,用于区分『用户自己发起的请求』和『第三方站点诱导浏览器发起的请求』。流程是:服务端生成令牌并下发到页面,前端在提交时回传,服务端比对与会话中保存的值是否一致。它的有效性取决于随机性、与会话的绑定关系以及轮换时机;把令牌放在 URL 查询串里,或全站长期复用同一个值,都会让防护效果大打折扣。

基本信息

生成要求密码学安全随机源,长度通常不少于 16 字节
绑定方式与会话或用户身份绑定,不跨用户复用
下发位置表单隐藏域或页面 meta 标签,前端读入自定义请求头
校验时机所有改变状态的请求(POST/PUT/DELETE)
轮换时机登录成功后重新生成,配合会话标识轮换

典型使用场景

  • 传统表单站点为每个表单嵌入隐藏字段,提交时由服务端比对
  • 前后端分离项目把令牌写入 meta 标签,前端读取后放入自定义请求头
  • 单页应用配合 SameSite Cookie 形成双层防护,浏览器兼容性与令牌校验互为补充
  • 登录、改密、转账等敏感操作单独校验并叠加二次确认
  • 接口开放场景评估是否改用其他机制(如自定义头 + 同源校验)

实现要点(伪代码)

实现要点(伪代码)
生成:密码学安全随机(>=16 字节),与会话绑定
下发:表单隐藏域或 meta 标签,前端读取后放入自定义头
校验:服务端比对会话中保存的值,不一致直接返回 403
轮换:登录成功后重新生成,同时轮换会话标识
范围:所有改变状态的请求都要校验,GET 不产生副作用

前端附加请求头示例

前端附加请求头示例
// 令牌放在页面 meta 中,前端读取后附加到请求头
const token = document.querySelector('meta[name=csrf-token]').content;

fetch('/api/transfer', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-CSRF-Token': token,   // 服务端据此与会话中的值比对
  },
  credentials: 'same-origin',  // 携带 Cookie 但限定同源
  body: JSON.stringify(payload),
});
令牌不要放在 URL 查询串:它会进入访问日志、Referer 头与浏览器历史,等于把校验凭据公开在多个位置。
纯接口服务若只提供自定义请求头且不允许跨域携带凭据,攻击难度本身较高;此时仍建议保留同源校验或令牌机制,避免后续放开跨域时留下缺口。

易错点

  • 令牌全站复用且长期不变:一旦通过脚本、日志或浏览器历史泄露,防护效果大打折扣
  • 只校验表单提交不校验接口请求:攻击者直接调用接口即可绕过
  • 令牌放在 URL 中传递:被访问日志与 Referer 记录,等同于泄露
  • 登录后不轮换令牌与会话标识:会话固定类问题可与 CSRF 叠加放大

数据来源与参考

  • OWASP CSRF Prevention Cheat Sheet(Synchronizer Token Pattern)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌