CSRF攻击防御使用Token还是Referer

wen 网络安全 2

本文目录导读:

CSRF攻击防御使用Token还是Referer

  1. 为什么推荐使用 Token?
  2. 为什么不推荐单独依赖 Referer?
  3. 实际中如何选择?
  4. 最佳实践:组合防御
  5. 总结对比表
  6. 实际代码示例(伪代码)

在防御CSRF攻击时,优先推荐使用 CSRF Token,而不是单纯依赖 Referer。

简要结论:Token 是主流、标准、可靠的防御方式;Referer 仅能作为辅助或降级方案,不可单独依赖。

以下是两者的详细对比分析:

为什么推荐使用 Token?

  • 安全性与唯一性:Token 是服务器生成的、与用户会话绑定的随机字符串,攻击者无法提前获知,每次提交请求时,服务器验证 Token 是否匹配,从根本上防止了第三方网站构造合法请求。
  • 不受环境限制:Token 在浏览器中通过隐藏字段或自定义 HTTP 头传递,不依赖请求头信息。
  • 标准实践:主流框架(如 Spring Security、Django、Express.js)都内置了 CSRF Token 支持,实现简单且经过安全验证。

为什么不推荐单独依赖 Referer?

  • Referer 可被篡改或缺失
    • 用户访问 HTTPS 页面后,再通过 HTTP 发起请求时,某些浏览器会不发送 Referer 头。
    • 部分浏览器插件或安全软件可能会移除 Referer 头。
    • 攻击者可以通过修改 <form>enctype 或使用 Flash 等插件方式,在某些情况下伪造 Referer。
    • iframe、跨域请求、直接输入地址或书签访问也可能导致 Referer 为空。
  • 绕过风险:虽然 Referer 可以用于同源检查,但一旦攻击者发现某个你信任的域名存在 XSS 漏洞,可以利用该域名发起 CSRF 攻击,Referer 检测会被绕过。
  • 可靠性不足:Referer 是客户端携带的信息,不应该作为唯一的安全决策依据。

实际中如何选择?

场景 推荐方案
高安全性需求(如支付、登录、后台管理) 仅使用 Token,并可配合 SameSite Cookie
API 接口或非浏览器客户端 Token(通过请求头传递)
传统、低风险场景(如简单表单) Token 为主,可额外加入 Referer 检查作为纵深防御
无法实现 Token 的旧系统 必须加上 Referer 检查,并配合其他措施(如二次验证)

最佳实践:组合防御

现代 Web 安全推荐深度防御

  1. 首选CSRF Token(在表单中加入隐藏字段或通过 X-CSRF-Token 请求头发送)。
  2. 辅助SameSite Cookie 属性(设置为 StrictLax,能有效阻止第三方网站发起的跨站请求)。
  3. 环境补充Referer/Origin 头检查(作为第二层验证,拦截明显异常的请求)。
  4. 重要操作二次确认(如支付时要求输入密码或验证码)。

总结对比表

特性 CSRF Token Referer/Origin
安全性 高(与用户会话绑定,不可预测) 低(可缺失、可伪造)
实现复杂度 中等(需服务器存储和验证) 低(仅校验请求头)
适用场景 所有类型请求(GET/POST/API) 仅限依赖浏览器环境的表单请求
兼容性 所有浏览器正常 HTTPS 到 HTTP 可能丢失
推荐程度 ★★☆☆☆(仅作辅助)

实际代码示例(伪代码)

Token 防御:

# 服务端生成 Token 并注入表单
<form method="POST" action="/transfer">
  <input type="hidden" name="csrf_token" value="{{ token }}">
  <input type="text" name="amount">
</form>
# 服务端接收时验证
if request.form['csrf_token'] != session['csrf_token']:
    raise "CSRF Token 无效"

Referer 辅助检查:

def check_referer(request):
    referer = request.headers.get('Referer', '')
    # 检查是否以合法域名开头(只能作为辅助,不能百分百依赖)
    if not referer.startswith('https://yourdomain.com/'):
        # 可以记录日志或要求用户二次验证,但不应直接拒绝所有流量
        pass

最终建议: 只要你的项目条件允许,请一定使用 CSRF Token,如果旧的代码或框架无法支持 Token 生成,再考虑使用 Referer 作为临时应急方案,同时尽快升级替换。

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