关于CSRF防御

252 阅读2分钟

首先明确一点,攻击者在进行跨站攻击的时候是无法读取其他域名下的Cookie,那为什么CSRF攻击仍然有效?那是因为浏览器在发起请求时会自动附带与请求目标域名相关的Cookie,他们可以诱导用户的浏览器自动发动请求。

具体关于CSRF的介绍我就不说了,这里主要就预防措施展开。

CSRF预防措施

1. Cookie属性

  • 设置cookie的SameSite属性为Strict(完全禁止跨站请求携带cookie)或Lax(在部分跨站请求情况下允许携带cookie,但在GET请求时会被允许),防止第三方网站发起跨站请求。

  • 设置cookie的属性httpOnly属性为true,防止攻击者通过js获取Cookie。

2. 检查Referer或Origin头

  • 服务器端验证请求的Referer或Origin头是否来自可信任的源。

  • 注意:Referer头可以被一些浏览器隐藏或被用户禁用,不完全可靠。

3. CSRF_Token双重校验

这里拿Express+Vue3举例:

  • Express中:
//配置csurf中间件
let csrfProtection = csurf({ cookie: true })//未设置ignoreMethods属性时,get请求不走csurf校验
//获取csrftoken并设置cookie
app.get('/csrf-token', csrfProtection, (req, res) => {
  const token = req.csrfToken()
  res.cookie('_csrf_token', token, { httpOnly: true, sameSite: 'strict' })
  res.json({ csrfToken: token })
})
// 动态应用CSRF保护中间件
app.use((req, res, next) => {
  if (req.path === '/csrf-token') {
    return next();
  }
  csrfProtection = csurf({ cookie: true, ignoreMethods: ['HEAD', 'OPTIONS'] })//设置ignoreMethods使get请求也经过csurf校验
  csrfProtection(req, res, next);//将除'/csrf-token'路由的接口都引入csrfProtection中间件
});
//csurf错误处理
app.use((err, req, res, next) => {
  if (err.code !== 'EBADCSRFTOKEN') return next()
  res.status(403);
  res.cc('无权限', 403)
})
  • Vue3中,在根组件中获取csrfToken并存入store里,在封装的httpApi中将csrfToken加入请求拦截判断并写入请求头中,这样当服务端接收到客户端请求时,csurf会自动比对请求头和cookie中的csrfToken,由于页面每次刷新或打开时都会生成新的csrfToken并且攻击者无法读取其他域名下的cookie,以此来起到防御作用

结尾

此篇为web前端就CSRF学习笔记,如有错误及不足,欢迎指正