Rails 3 CSRF令牌仍然提交



我在一个遗留的rails应用程序中工作,我正在尝试清理一些CSRF漏洞。如果我从表格中删除隐藏的CSRF字段,我仍然可以成功提交表格。

出现问题的唯一指示是日志中的警告:WARNING: Can't verify CSRF token authenticity

在某些页面中,protect_from_forgery会捕获请求,如果没有csrf令牌,但它的命中率取决于页面,则应用程序会崩溃:例如,登录页面在没有令牌的情况下可以工作,但更新用户页面则不能。

我尝试为protect_from_forgery制定一个自定义策略(Marc Gauthier建议(,类似于:

protect_from_forgery with: :MyStrategy
class MyStrategy
byebug
def initialize(controller)
@contriller = controller
end
def handle_unverified_request
puts "HELLO!"
Rails.logger.warn [
"handle_unverified_request",
"#{@controller.controller_name}-#{@controller.action_name}"
].join(" - ")
end
end

在启动应用程序时,这似乎没有任何作用——byebug调用将暂停,但我从未收到puts消息或错误日志。

我也尝试过with: :exception等常规策略,但没有任何变化,有些页面有效,有些页面无效,但它们是一致的。

通常保护登录用户会话不受CSRF的影响是很重要的,因此在许多应用程序中,通常会在登录/注销时禁用保护,以防止合法用户出错。在大多数情况下,如果会话无论如何都要终止/重置,RF不会造成太大伤害。

查找skip_before_action :verify_authenticity_token禁用protect_from_forgery正在安装的操作

检查您的测试方法-隐藏的表单字段并不总是必需的,因为rails也使用ajax表单的X-CSRF-Token头。要正确测试伪造保护,请进行实际的伪造尝试,例如使用curl

检查config.action_controller.allow_forgery_protection是否未被禁用用于开发/生产,并且控制器或其祖先没有使allow_forgery_protection过载并为有问题的请求返回false。不太可能,但应用程序可能忽略了伪造保护的其他部分,请参阅request_forgery_protection.rb

PS。类上下文中的byebug对这种情况不是很有用,更明显的方法是在handle_unverified_request中使用raise "Hello CSRF"

Rails似乎在做它应该做的事情,只是重置会话,这在登录表单或忘记密码表单上并不重要。因为我们只有protect_from_forgery(with: :exception直到Rails 5中的某个时候才成为默认值(。

人们可能会认为添加with: :exception会起作用,但事实并非如此。解决方法是提取Exception类的内容并将其放入application_controller:

def handle_unverified_request
raise ActionController::InvalidAuthenticityToken
end

这适用于登录和忘记密码表单,其他表单(正确地不允许错误请求通过(保持不变,这有点奇怪,因为我认为InvalidAuthenticityToken raised会同时失败。

当然,这就留下了一个问题,为什么protect_from_forgery with: :exception不起作用?

相关内容

  • 没有找到相关文章

最新更新