在我的一个控制器中,我编写以下内容以保护CSRF中的某些页面 .
protect_from_forgery :only => [:foo, :bar]
当我加载对应于 foo
和 bar
的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 回答
CSRF令牌存储在用户的会话中(默认情况下,在Rails中为cookie;在Rails 4中为加密cookie) . 它还通过
csrf_meta_tags
帮助方法作为<meta>
标记(供Javascript库使用)写入页面,并在页面中由form_tag
或form_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 (无论如何都不会通过集合) ),所以你最终测试两个不同的东西,由于错误的原因产生正确的结果 .