← 中文资源

简体中文版本

安全地刷新双重提交 CSRF 令牌

在可读 Cookie 中下发随机 CSRF 令牌并要求请求头携带,登录时刷新,并用常量时间比较校验。

阅读英文原文

概述

单页应用在登录后仍持旧令牌,会让合法写入一直 403,直到整页刷新。双重提交模式简单有效,但必须处理令牌轮换与 SameSite 属性,否则要么误伤合法请求,要么留下跨站漏洞。

关键步骤

  1. 在 JS 可读的 Cookie 中下发随机 CSRF 令牌。
  2. 对状态变更方法要求在请求头中携带同一令牌。
  3. 服务端用常量时间比较头与 Cookie 取值。
  4. 在登录、登出与权限变更时轮换令牌。

验证

  • 状态变更请求缺少匹配令牌时返回 403。
  • 合法请求在令牌刷新后继续成功。
  • 比较为常量时间,不泄露时序。
  • 跨站请求无法伪造匹配的头。

注意事项

  • 双重提交依赖浏览器不允许跨站读取该 Cookie,取决于正确的 SameSite 设置。
  • 除非结合严格的 Cookie 属性,否则弱于与会话绑定的同步令牌。

适用范围

本条目围绕「安全地刷新双重提交 CSRF 令牌」给出可复制的步骤、验证方式与常见问题,适合需要按此流程落地的工程团队。执行时请结合自身上下文调整命令与阈值,并在变更前后留存证据,便于后续复核与回滚。

app.use((req, res, next) => {
  if (['POST','PUT','PATCH','DELETE'].includes(req.method)) {
    if (!timingSafeEqual2(req.cookies.csrf, req.get('X-CSRF-Token'))) {
      return res.status(403).json({ error: { code: 'csrf' } });
    }
  }
  next();
});