【问题标题】:Where does Rails 4 store the authentication token for CSRF protection?Rails 4 在哪里存储用于 CSRF 保护的身份验证令牌?
【发布时间】:2014-06-21 08:38:26
【问题描述】:

在我的一个控制器中,我编写了以下代码来保护某些页面免受 CSRF 影响。

  protect_from_forgery :only => [:foo, :bar]

当我加载对应于foobar 的URL 并查看HTML 时,我看不到任何隐藏的输入字段或包含任何安全令牌的元标记,如here 所述。

但是,在测试期间,我确实观察到CSRF 对这些页面无效,尽管它对同一应用程序中不受保护的其他页面有效。

那么Rails 4 将用于验证请求是否来自原始页面的安全令牌存储在哪里?

请注意,我已经通读了Ruby On Rails Security Guide,并且从protect_from_forgery 的部分中,它说

这将自动在所有表单和 Ajax 中包含一个安全令牌 Rails 生成的请求。如果安全令牌与什么不匹配 是预期的,会话将被重置。

问题在于,在启用 CSRF 保护的页面上,表单中似乎缺少此安全令牌,即使 CSRF 确实对它们无效。


请注意,此代码来自class project,其中一个目标是执行点击劫持攻击以绕过 CSRF 项目。我在这里问的问题是与作业的目的正​​交

我只是好奇 Rails 究竟是如何处理 CSRF 的。

直接执行rails server后,我找不到安全令牌的相关URL是http://localhost:3000/protected_transfer

【问题讨论】:

    标签: ruby-on-rails security csrf csrf-protection


    【解决方案1】:

    CSRF 令牌存储在用户的会话中(在 Rails 中默认保存在 cookie 中;在 Rails 4 中是加密的 cookie)。它还通过csrf_meta_tags 辅助方法作为<meta> 标记(供Javascript 库使用)写入页面,并在页面中form_tagform_for 生成的任何形式的隐藏字段中写入。

    查看这个项目,没有出现 CSRF 令牌的原因是 HTML 是用文字 <form> 标签编写的,而不是 form_for 帮助器,后者将包含 CSRF 令牌。此外,csrf_meta_tags 助手不在布局中,这就是元标记没有被写入的原因。

    该表单被硬编码以发布到 <form action="post_transfer" method="post">,它不应受到 CSRF 保护,因此该表单应该支持 CSRF,即使视图标记为 protect_from_forgeryprotected_post_transfer 方法甚至不可能接受合法请求,因为从不发送真实性令牌。

    我怀疑教师错过了这一点,因为测试将是合法地使用表格(点击未验证的端点,并让它成功),然后指示学生尝试针对受保护的端点进行 CSRF(这永远不会无论如何都通过了),所以你最终会测试两种不同的东西,因为错误的原因会产生正确的结果。

    【讨论】:

    • 感谢您实际查看项目代码。令人惊讶的是,它确实接受合法请求,现在我正在摸不着头脑,试图了解原因。
    • 它发布到post_transfer(表单操作是硬编码的)而不是protected_post_transfer,所以它实际上应该容易受到CSRF的攻击。你确定不是吗?
    • 很好的收获!看来是导师搞砸了。我会把它指向protected_post_transfer,看看它是否仍然接受任何请求。
    • 对于它的价值,这就是为什么form_for 和 Rails 路径助手很好 - 他们为你管理所有这些东西,所以这些类型的错误不会出现!跨度>
    • 你完全正确。当protected_post_transfer 被命中时,此代码 接受合法请求。这回答了问题,尽管不是我预期的方式。
    猜你喜欢
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    • 2014-10-28
    • 1970-01-01
    相关资源
    最近更新 更多