为什么恶意网站在攻击之前无法通过GET获取CSRF令牌?

时间:2016-11-28 09:51:45

标签: ajax security browser csrf csrf-protection

如果我理解正确,在CSRF攻击中,恶意网站 A 会告诉我的浏览器向网站 B 发送请求。我的浏览器会自动在该请求中包含我的 B Cookie。虽然 A 无法看到这些Cookie,但如果我已经在 B 中进行了身份验证,则该请求看起来是合法的,并且无论采取何种操作都将成功执行。为避免这种情况,每当我访问包含表单的 B 页面时,我都会收到一个CSRF令牌。此令牌与我的会话相关联,因此如果我对 B 进行POST,我必须包含此类令牌;否则 B 拒绝我的请求。该方案的好处是 A 无法访问该令牌。

我有两个问题:

  • 上述说明是否正确?
  • 如果是这样,为什么网站 A 首先告诉我的浏览器发送GET到 B ,从响应中获取CSRF令牌,然后使用现在发送POST给 B 的令牌?请注意,令牌有效并与我的会话相关联,因为GET还包含我的所有 B Cookie。

谢谢!

2 个答案:

答案 0 :(得分:5)

您的描述是正确的。

如果站点A告诉您的浏览器转到B并获取令牌,那很好,但因为它是跨域请求,A将无法访问Javascript中的令牌(这是一个浏览器功能)。因此,当A告诉您的浏览器返回B并实际执行某些操作时,它仍然无法在请求中包含该令牌。

即,除非B将令牌设置为cookie。显然,这将是有缺陷的,因为令牌cookie也将被发送,从而否定任何保护。因此,在这种情况下,令牌必须作为表单值或请求标头(或其他不像cookie一样自动发送的内容)发送。

这也意味着如果B容易受到跨站点脚本攻击,它也容易受到CSRF的攻击,因为令牌可能会被盗,但CSRF则是一个较小的问题。 :)

答案 1 :(得分:1)

正确。

由于浏览器的CORS策略,网站A无法获得网站B的csrf令牌。

我们需要验证请求referer(可以伪造)。 https://en.wikipedia.org/wiki/HTTP_referer

在url(AKA查询字符串)中验证crsf令牌也是一种很好的做法。

仅供参考,Laravel,一个流行的Web框架,在表单中使用隐藏的CSRF令牌字段来防止csrf攻击。