如何修复多个休息端点的 Brakeman 重定向问题

How to fix Brakeman redirect issue with multiple rest endpoints

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

这是给我一个 Brakeman 警告,可以在下面找到 link

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

 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

我已经尝试通过使用 RoR 中的 redirect_back 方法来修复此问题,但那是使用我不想使用的创建方法的引用 link。

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

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

你也可以争辩说 referer header 在技术上是用户输入,你将重定向到它,但我想说在大多数情况下和现代浏览器这可能是可以接受的风险,因为攻击者并没有真正利用它的方法(但这可能取决于具体情况)。

对于类似情况,立即想到的一个解决方案是 session - 但一方面,如果我理解正确的话,这是休息 api,所以没有 session,另一方面,它仍然无法抵御攻击者 link 从恶意域访问您的 #new 端点。

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

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