← 中文资源

简体中文版本

用双重提交防御 CSRF

结合 SameSite Cookie 与双重提交令牌,使跨站请求无法伪造有副作用的操作。

阅读英文原文

目标

有副作用的接口只接受会话 Cookie 而无防 CSRF 令牌,跨站表单即可代替用户操作。本配方下发可被本站脚本读取的 CSRF Cookie,并要求状态变更请求在头部携带相同令牌,从而阻断跨站伪造;同时把会话 Cookie 设为 SameSite 与 httpOnly,形成纵深防御。

步骤要点

  1. 下发可读的 CSRF Cookie 并要求头部携带相同令牌。
  2. 对状态变更方法校验头部令牌。
  3. 把会话 Cookie 设为 SameSite 且 httpOnly。
  4. 对合法的跨站 POST 采用令牌交换流程而非放宽校验。
res.cookie('csrf', token, { sameSite: 'lax', secure: true, httpOnly: false });
app.use((req, res, next) => {
  if (['POST','PUT','PATCH','DELETE'].includes(req.method)) {
    const header = req.get('x-csrf-token');
    if (!header || header !== req.cookies.csrf) return res.status(403).end();
  }
  next();
});

排错提示

  • 跨站合法请求会失败,应改用令牌交换。
  • CSRF Cookie 需可被脚本读取、会话 Cookie 需 httpOnly。
  • 子域攻击可能绕过,需收紧 Cookie 作用域。

适用边界

  • 依赖 Cookie 作用域正确。
  • 不能替代输入校验。