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



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

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

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

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

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

请注意,我已经通读了Ruby On Rails安全指南,从protect_from_forgery部分来看,它说

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

问题是这个安全令牌似乎在启用了CSRF保护的页面上的表单中丢失了,尽管CSRF确实对它们无效。


注意,这段代码来自一个类项目,其中一个目标是执行clickjacking攻击来绕过CSRF项目。我在这里问的问题是与赋值的目的无关。

我只是好奇Rails到底是如何实现CSRF的。

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

CSRF令牌存储在用户的会话中(在Rails中默认存储在cookie中;它通过csrf_meta_tags助手方法作为<meta>标签(供Javascript库使用)以及在页面中由form_tagform_for生成的任何表单中作为隐藏字段写入页面。

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

这个表单是硬编码到<form action="post_transfer" method="post">的,不应该被CSRF保护,所以这个表单应该是CSRF-able的,即使视图被标记为protect_from_forgeryprotected_post_transfer方法甚至不可能接受合法的请求,因为真实性令牌永远不会发送。

我怀疑指导员错过了这一点,因为测试将合法地使用表单(击中未验证的端点,并让它成功),然后指示学生尝试对受保护的端点进行CSRF(无论如何都不会通过检查),因此您最终测试了两种不同的东西,它们出于错误的原因产生了正确的结果。

最新更新