为什么 Rails 中的 CSRF 令牌不会阻止多个选项卡正常工作?

2024-05-23

在阅读了 Rails 中 CSRF 保护的工作原理后,我尝试通过执行以下操作来触发 CSRF 保护:

注意:我们使用基于 cookie 的会话。

  1. 访问登录页面。检查元中的 CSRF 令牌 => abc123
  2. 打开第二个浏览器选项卡,然后访问相同的登录页面。元中的 CSRF 令牌不同 => def456
  3. 返回第一个选项卡。
  4. 提交登录凭据。

我预计这会失败,因为第二个选项卡生成了一个新的、不同的 CSRF 令牌。当登录表单提交时,提交到服务器的令牌不应该是旧的、过时的令牌吗?

然而,这does work:

  1. 访问登录页面。检查元中的 CSRF 令牌 => abc123
  2. 打开第二个浏览器选项卡,然后访问相同的登录页面。元中的 CSRF 令牌不同 => def456
  3. 返回第一个选项卡。
  4. 提交登录凭据。
  5. 注销(清除会话)
  6. 转到第二个选项卡,然后提交登录。

在这种情况下,我按预期收到 InvalidAuthenticityToken 异常。为什么?


Source: https://medium.com/rubyinside/a-deep-dive-into-csrf-protection-in-rails-19fa0a42c0ef https://medium.com/rubyinside/a-deep-dive-into-csrf-protection-in-rails-19fa0a42c0ef

为什么第二个选项卡中的请求没有失败

CSRF 令牌位于meta标签实际上是两个字符串的串联:每个请求生成的“一次性密码本”,以及与一次性密码本进行异或运算的“真实”CSRF 秘密。请参见下图,一次性填充如何添加到屏蔽令牌中的异或字符串之前,该字符串存储在meta tag:

Rails 将 CSRF 秘密存储在会话 cookie 中,而不进行异或运算。应该在浏览器中使用 JavaScript 从meta标记并将其传递到X-CSRF-TOKEN header.

当 Rails 验证请求时,它:

  1. 分割传入的值X-CSRF-TOKEN用于检索一次性填充和异或字符串的标头。
  2. 将它们异或在一起以检索真正的秘密。
  3. 将其与 cookie 中的秘密进行比较。

这就是为什么您会看到令牌不断变化的原因meta标签——一次性便签本是不同的。如果您验证了令牌,您会在两个令牌中发现相同的秘密。

Note:这种一次性便笺业务似乎没有必要。如果任何人拥有被掩盖的令牌,他们都可以检索真正的秘密。令人惊讶的是,XORing 的目的是在每个请求上更改 CSRF 令牌,以便攻击者无法使用定时攻击来辨别秘密。看本文介绍 BREACH SSL 攻击 http://breachattack.com/resources/BREACH%20-%20SSL,%20gone%20in%2030%20seconds.pdf.

为什么请求在注销时失败

如中所述@max的评论 https://stackoverflow.com/questions/47723379/why-does-the-csrf-token-in-rails-not-prevent-multiple-tabs-from-working-properly#comment82408038_47723379,注销会删除会话 cookie。下一个请求会生成一个新的 CSRF 密钥,该密钥不再与旧的屏蔽令牌相匹配。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Rails 中的 CSRF 令牌不会阻止多个选项卡正常工作? 的相关文章

随机推荐