为什么经常使用 CSRF 代币?

信息安全 Web应用程序 csrf
2021-08-17 19:43:44

CSRF 令牌被大量使用

服务器在该域的 cookie 中设置一个令牌,该令牌 (1) 包含在 HTML 表单中或 (2) Javascript 可以读取并包含在请求中。服务器验证请求中的令牌与 cookie 中的令牌匹配。


但是为什么不简单地检查 Origin 标头呢?根据OWASP,这就是它存在的原因:

引入了 Origin HTTP 标头标准作为防御 CSRF 和其他跨域攻击的方法。

“起源不存在吗?如果不存在,好的。如果存在,它是我信任的一个吗(例如,相同的起源)?如果是,好的。”


CSRF 令牌可能很麻烦。他们是

  • 初学者更难理解——“等等……我发了两次?又是什么 CRSF?”
  • 需要 cookie(授予,通常不是问题)
  • 更难实现——需要控制器视图
  • 不太灵活——永远不能跨域工作
  • 在非网络设置中很奇怪——“为什么你的 API 需要 CSRF 令牌?” “哦,因为 JS 也使用它。”
  • 全局实现更麻烦——“糟糕,在我的 25 个 HTML 表单字段中忘记了 CSRF 标记”

鉴于这些缺点,为什么 CSRF 令牌如此常用,而不是 Origin 标头?

2个回答

您目前不能依赖 Origin 标头,因为它并未在所有正在使用的浏览器中实现。除此之外,并非在所有与 CSRF 相关的情况下都发送 Origin,例如

<img src=http://router/admin.cgi?...>

“起源不存在吗?如果不存在,好的。如果存在,它是我信任的一个吗(例如,相同的起源)?如果是,好的。”

虽然您可以使用 Origin 标头来拒绝请求。如果缺少 Origin 标头,您将无法安全地接受它,即使对于 POST 请求也是如此。据我所知,HTML 表单请求不包含 Origin 标头,img、脚本、链接、cos 背景图像或其他发出 get 请求的地方也不包含。当然,Origin 标头不会针对同一主机上的 XHR 请求发送,因此您需要另一种保护机制。

一种选择是将 csrf 令牌放在自定义标头中,这更容易在全局范围内执行,并且不会将令牌放在获取请求的 URL 中。然后,如果需要,您可以检查请求是否具有 Origin 标头或自定义标头。

如果您拒绝任何不是 Ajax 请求的请求,您也可以执行您提到的方法。但我对它的安全性没有信心。

简而言之,如果你想发出同源请求,Origin 标头本身是不够的,但可以与另一种 csrf 保护方法结合使用。