概述
单页应用在登录后仍持旧令牌,会让合法写入一直 403,直到整页刷新。双重提交模式简单有效,但必须处理令牌轮换与 SameSite 属性,否则要么误伤合法请求,要么留下跨站漏洞。
关键步骤
- 在 JS 可读的 Cookie 中下发随机 CSRF 令牌。
- 对状态变更方法要求在请求头中携带同一令牌。
- 服务端用常量时间比较头与 Cookie 取值。
- 在登录、登出与权限变更时轮换令牌。
验证
- 状态变更请求缺少匹配令牌时返回 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();
});