0

我目前正在研究在 RoR 中进行重定向的解决方案,因为我在刹车报告中收到一个错误,说我必须以正确的方式修复重定向。我了解消息的内容以及如何在一个控制器操作中解决它。但现在我得到了以下内容。在新方法的实例化过程中,我设置了可在创建操作中使用的 HTTP_REFERER 标头。

这给了我一个 Brakeman 警告,可以在以下链接中找到

假设我有以下具有多个端点的控制器:

 def new
      @my_model_set = MyModel.new
      @referer = request.env['HTTP_REFERER'] # We want to redirect to this referer after a create
 end
def create
  ...
  if @my_model_set.save
     flash_message :success, t('notification.item_created', type: @my_model_set.model_name.human)
     if params[:referer].present?
          redirect_to params[:referer]
     else
          redirect_to admin_my_model_set_path
     end
  else
  ...
  end
end

我已经尝试通过使用redirect_back来自 RoR 的方法来解决这个问题,但这是使用我不想使用的 create 方法的引用链接。

if @my_model_set.save
    flash_message :success, t('notification.item_created', type: @my_model_set.model_name.human)
    redirect_back(fallback_location: admin_my_model_set_path)
else
 ...
end

4

1 回答 1

2

您的代码中的主要问题是,params[:referer]您的用户(或为您的用户伪造链接的攻击者)可以通过附加?referer=https://malicious.site到 url 将其设置为任意值。然后,您将重定向到那个,这是一个开放的重定向漏洞。

您也可以争辩说,从referer技术上讲,标头是用户输入,并且您将重定向到它,但我会说在大多数情况下,现代浏览器可能是可接受的风险,因为攻击者实际上没有办法利用它(但这可能取决于具体情况)。

对于类似情况,立即想到的一个解决方案是会话 - 但一方面,如果我理解正确,这是一个休息 api,所以没有会话,另一方面,它仍然不安全攻击者#new从恶意域链接到您的端点。

我认为您应该在重定向到之前验证域。如果有一个共同的模式(例如,如果所有这些都是 yourdomain.com 的子域),请对此进行验证。或者您可以让您的用户在重定向到之前先注册他们的域(例如,查看 OAuth2 的工作原理,您必须先注册您的应用程序域,然后用户才能使用令牌重定向到那里)。

如果您的用户可能只是来自任何地方,#new并且您想将他们发送回他们来自的任何地方 - 我认为这不是一个好的要求,您可能不应该这样做,或者您应该仔细评估风险并有意识地接受它,如果您出于某种原因想要。在大多数情况下,有更安全的解决方案。

于 2020-05-26T12:21:00.443 回答