首页 文章

Rails 4在哪里存储用于CSRF保护的身份验证令牌?

提问于
浏览
5

在我的一个控制器中,我编写以下内容以保护CSRF中的某些页面 .

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

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

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

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

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

这将自动包含所有表单中的安全令牌和Rails生成的Ajax请求 . 如果安全令牌与预期的不匹配,则会重置会话 .

问题是启用了CSRF保护的页面上的 this security token appears to be missing from the forms ,即使CSRF确实对它们无效 .


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

我只是对Rails如何做CSRF感到好奇 .

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

1 回答

  • 10

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

    看看这个项目,没有出现CSRF令牌的原因是HTML是用文字 <form> 标签写的,而不是包含CSRF令牌的 form_for 助手 . 此外,布局中不存在 csrf_meta_tags 帮助程序,这就是无法编写元标记的原因 .

    表单被硬编码以发布到 <form action="post_transfer" method="post"> ,不应受CSRF保护,因此即使视图标记为 protect_from_forgery ,此表单也应该是CSRF能力的 . protected_post_transfer 方法甚至不可能接受合法请求,因为永远不会发送真实性令牌 .

    我怀疑导师错过了这个,因为测试将合法地使用表格(击中未经验证的 endpoints ,并让它成功),然后指示学生尝试CSRF对抗受保护的 endpoints (无论如何都不会通过集合) ),所以你最终测试两个不同的东西,由于错误的原因产生正确的结果 .

相关问题