Skip to content

CSRF 攻击的防御方案

更新: 5/24/2026 字数: 0 字 时长: 0 分钟

防御 CSRF 的核心思路只有一个:让正规站点能够识别"这个请求到底是不是用户本人在本站点上主动发起的"。围绕这个目标,业界形成了从服务端到客户端、从协议层到业务层的多重防御体系。

一、服务端防御(核心手段)

1. CSRF Token(同步令牌模式,最主流方案)

原理:服务端为每个用户会话生成一个不可预测的随机令牌,要求所有敏感请求必须额外携带这个令牌,且令牌不能放在 Cookie 中。

完整流程

  1. 用户访问表单页面时,服务端在 HTML 中嵌入一个隐藏字段 <input type="hidden" name="csrf_token" value="随机字符串">,同时把该 Token 存入服务端 Session。
  2. 用户提交请求时,浏览器把 Token 一并发送给服务端。
  3. 服务端比对"请求中的 Token"与"Session 中的 Token",一致才放行。

为什么有效:恶意站点由于同源策略限制,无法读取正规站点页面中的 Token,伪造的请求里没有 Token 或 Token 错误,直接被拒绝。

注意事项

  • Token 必须足够随机(使用密码学安全的随机数生成器)。
  • Token 不能放在 URL 中(易通过 Referer 泄露)。
  • 一次性 Token 安全性更高,但会话级 Token 实现更简单,按场景选择。

原理:服务端生成随机值,同时写入 Cookie 和返回给前端,前端在提交请求时把该值放入请求头或表单参数。服务端校验"Cookie 中的值"与"请求参数中的值"是否一致。

为什么有效:恶意站点虽然能让浏览器自动带上 Cookie,但读不到 Cookie 的内容(受同源策略保护),因此无法在请求参数中放入匹配值。

适用场景:无 Session 的分布式系统、纯前后端分离架构,无需服务端存储状态。

注意事项:需配合 SecureHttpOnly 之外的合适 Cookie 属性,避免子域被攻击者控制后绕过。

原理:通过给 Cookie 设置 SameSite 属性,告诉浏览器"跨站请求时是否携带该 Cookie"。

取值行为防御效果
Strict任何跨站请求都不携带 Cookie最强,但用户体验差(从外站点跳转进来会丢失登录态)
Lax仅在顶级导航的 GET 请求(如点击链接)携带,跨站的 POST/iframe/img 等不携带当前主流浏览器的默认值,平衡安全与体验
None任何跨站请求都携带(必须同时设置 Secure无 CSRF 防护,仅在确实需要跨站 Cookie 时使用

推荐做法:敏感 Cookie 统一设置 SameSite=LaxStrict,并配合 SecureHttpOnly

注意:SameSite 是纵深防御,不能完全替代 CSRF Token。老旧浏览器不支持,且 Lax 模式下仍可能被 GET 型 CSRF 利用。

4. 校验 Referer / Origin 请求头

原理:HTTP 请求头中的 OriginReferer 标识了请求来源页面,服务端校验来源是否为本站合法域名。

  • Origin:优先校验,POST/PUT/DELETE 等请求通常会自动携带,且不包含路径,更适合做来源判断。
  • Referer:作为兜底校验。

局限性

  • 用户/浏览器可能因隐私设置禁用 Referer。
  • 某些场景下 Referer 不会被发送(如 HTTPS → HTTP 跳转)。
  • 仅作为辅助校验,不建议作为唯一防线。

5. 关键操作二次验证

高敏感操作(转账、改密码、删除账号等),强制要求用户额外输入:

  • 短信验证码 / 邮箱验证码
  • 图形验证码
  • 二次输入登录密码
  • 生物识别 / U 盾 / 硬件密钥

为什么有效:即使 CSRF 请求成功发出,攻击者无法获取这些动态信息,操作仍会被阻断。这是金融级场景的最后一道防线

二、规范层面的防御

6. 严格遵循 HTTP 方法语义

  • GET 请求只用于查询,绝不执行任何状态变更操作(不要做转账、删除、修改)。
  • 状态变更操作必须使用 POST / PUT / DELETE。

为什么重要:GET 型 CSRF 只要一张 <img> 就能触发,门槛极低;强制使用非 GET 方法后,攻击者必须构造表单或 AJAX,配合 SameSite=Lax 即可大幅减少攻击面。

7. 自定义请求头 + CORS 校验

要求所有 AJAX 请求携带自定义请求头(如 X-Requested-With: XMLHttpRequestX-CSRF-Token)。

为什么有效:浏览器对带自定义头的跨域请求会触发 CORS 预检(Preflight),恶意站点没有正规站点的 CORS 许可,预检直接失败,真实请求根本不会发出。

三、用户侧建议(辅助)

  • 使用敏感网站后及时登出,缩短登录态有效窗口。
  • 不要在登录敏感账户的浏览器中随意点击不明链接
  • 使用浏览器隐私模式 / 多账号容器隔离不同站点的会话。
  • 保持浏览器更新,启用现代浏览器的默认安全策略。

四、推荐的纵深防御组合

单一手段都有局限,生产环境建议组合使用

层级防御措施优先级
协议层SameSite=Lax/Strict + Secure + HttpOnly Cookie必选
应用层CSRF Token(或 Double Submit Cookie)必选
接口层校验 Origin / Referer推荐
规范层严格区分 GET 与状态变更方法必选
业务层关键操作二次验证(验证码 / 密码 / OTP)高敏感场景必选

一句话总结

防御 CSRF 的本质,是让"伪造的请求"无法通过身份与来源的双重校验。 Cookie 解决"你是谁",Token / SameSite / Origin 解决"这个请求是不是你真的想发"——两者缺一不可。