目标
有副作用的接口只接受会话 Cookie 而无防 CSRF 令牌,跨站表单即可代替用户操作。本配方下发可被本站脚本读取的 CSRF Cookie,并要求状态变更请求在头部携带相同令牌,从而阻断跨站伪造;同时把会话 Cookie 设为 SameSite 与 httpOnly,形成纵深防御。
步骤要点
- 下发可读的 CSRF Cookie 并要求头部携带相同令牌。
- 对状态变更方法校验头部令牌。
- 把会话 Cookie 设为 SameSite 且 httpOnly。
- 对合法的跨站 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 作用域正确。
- 不能替代输入校验。