如何修复多个休息端点的 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
,而您想将他们送回他们来自的任何地方 - 我认为这不是一个好的要求,您可能不应该这样做,或者您应该这样做仔细评估风险并自觉地接受它,如果你出于某种原因想要接受它。在大多数情况下,有更安全的解决方案。
我目前正在研究在 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
,而您想将他们送回他们来自的任何地方 - 我认为这不是一个好的要求,您可能不应该这样做,或者您应该这样做仔细评估风险并自觉地接受它,如果你出于某种原因想要接受它。在大多数情况下,有更安全的解决方案。