跨站请求伪造怎么防护?

wen 开源项目 69

本文目录导读:

跨站请求伪造怎么防护?

  1. 最核心、最通用的方法:CSRF Token(同步令牌模式)
  2. 辅助增强:同源检测(Referer / Origin Header)
  3. 针对特定场景:SameSite Cookie 属性
  4. 用户交互验证(二次确认)
  5. 其他辅助措施
  6. 总结与最佳实践建议

跨站请求伪造(CSRF/XSRF)是一种常见的Web安全攻击,攻击者诱导用户点击恶意链接或访问恶意网站,利用用户已在目标网站登录的身份,在用户不知情的情况下执行非本意的操作(如转账、修改密码等)。

有效的防护策略通常从服务器端客户端两方面入手,以下是核心防护手段:

最核心、最通用的方法:CSRF Token(同步令牌模式)

这是目前使用最广泛的防护方式,几乎所有主流Web框架(如Spring Security、Django、Laravel)都内置支持。

  • 原理:服务器生成一个随机且难以猜测的Token(令牌),存储在用户的Session(会话)中,当渲染包含敏感操作的表单或请求时,将这个Token作为隐藏字段或请求头发送给客户端,客户端在提交请求时,必须携带这个Token,服务器收到请求后,验证Token是否与Session中的一致。
  • 防护点:攻击者的恶意站点无法获取目标站点为用户生成的Token(受同源策略限制),因此无法构造有效的恶意请求。
  • 实现方式
    • 表单隐藏域<input type="hidden" name="_csrf_token" value="随机字符串">
    • 请求头:通过JavaScript(JS)在AJAX请求的X-CSRF-Token头中携带Token。

辅助增强:同源检测(Referer / Origin Header)

服务器通过检查HTTP请求头中的RefererOrigin字段,判断请求是否来自本网站的合法页面。

  • Origin检查:更安全,它只包含协议、域名和端口,不包含路径,服务器可以明确检查Origin头是否在允许的白名单中。
  • Referer检查:包含完整URL,可作为备选方案,但存在少量情况(如HTTPS跳转到HTTP时浏览器可能不发送Referer)、以及浏览器插件或代理可能修改该字段,因此可靠性略低于Origin检查。
  • 适用场景:常用于API(应用程序编程接口)接口或无法方便使用Token的场景(如图片请求)。

针对特定场景:SameSite Cookie 属性

这是现代浏览器提供的一种强大且无需开发者额外编码的防护机制,通过在设置Cookie时指定SameSite属性,可以有效防止浏览器在跨站点请求时发送Cookie。

  • SameSite=Strict(严格模式):最严格,只要是从其他站点(点击链接、提交表单、加载图片)发起的请求,浏览器都不会发送该Cookie,适合银行、支付等安全要求极高的操作。
  • SameSite=Lax(宽松模式,现代浏览器的默认值):在大多数跨站请求中不会发送Cookie(如加载图片、iframe(内联框架)),但允许安全的顶级导航(如用户通过GET方式点击一个链接访问你的网站)携带Cookie,这是安全性与用户体验之间的良好平衡,适合大多数网站。
  • SameSite=None:禁用SameSite防护,允许所有跨站请求携带Cookie,但必须配合Secure(仅HTTPS)属性使用。

用户交互验证(二次确认)

对于高风险操作(如转账、删除账号、修改安全设置),强制要求用户进行二次交互验证。

  • 验证码(CAPTCHA):要求用户输入图形或声音验证码,攻击者无法自动化绕过。
  • 重新输入密码/短信验证码:要求用户再次输入登录密码或手机验证码,这是最高级别的防护,能有效阻止CSRF,同时也防止了“会话劫持”等其他攻击。

其他辅助措施

  • 使用POST请求处理状态变更:避免使用GET请求(如 https://bank.com/transfer?to=attacker&amount=1000)来执行修改数据或状态的敏感操作,恶意网站可以通过<img>标签轻松发起GET请求。
  • 自定义请求头:要求所有AJAX请求必须携带一个自定义头,如X-Requested-With: XMLHttpRequest,由于同源策略,恶意网站无法添加这个头,这常用于API防护。
  • 双重Cookie提交:在Cookie中设置一个随机值,同时在请求体或请求头中也发送该值,服务器比较两者是否一致,此方法无需Session存储,但需要确保Cookie本身不被窃取。

总结与最佳实践建议

  1. 首选方案CSRF Token + SameSite Cookie,这是现代Web应用最推荐的双保险组合。
  2. 对敏感操作:在CSRF Token的基础上,增加用户交互验证(如短信验证码)。
  3. 框架依赖使用成熟的Web框架,大多数现代Web框架(Spring Boot、Django、Ruby on Rails、Express.js等)内置了完善的CSRF防护,直接启用即可,避免自己手动实现。
  4. 检查API:如果你的后端提供REST API给前端或移动端,确保API严格验证Token或使用双重Cookie提交自定义请求头
  5. 避免误区:不要使用URL重写(在URL中携带Session ID)来防护CSRF,这反而会严重增加Session固定攻击的风险。

一句话核心:让服务器能区分“用户本人意图发起的请求”和“攻击者伪造的请求”。

抱歉,评论功能暂时关闭!