Ruby on rails Refile Gem:当远程图像url无效或不';不存在

Ruby on rails Refile Gem:当远程图像url无效或不';不存在,ruby-on-rails,ruby-on-rails-4,refile,Ruby On Rails,Ruby On Rails 4,Refile,我们使用它允许用户将图像上传到我们的S3后端。此外,我们允许用户输入指向internet上任何图像的URL(通过remote\u image\u URL属性) 只要输入的URL指向实际文件,这种方法就可以正常工作。但是,如果URL中有错误,或者提供了一些无意义的输入,Refile将抛出以下异常: Errno::ENOENT (No such file or directory @ rb_sysopen - thiswillnotwork): app/controllers/my/deals_

我们使用它允许用户将图像上传到我们的S3后端。此外,我们允许用户输入指向internet上任何图像的URL(通过
remote\u image\u URL
属性)

只要输入的URL指向实际文件,这种方法就可以正常工作。但是,如果URL中有错误,或者提供了一些无意义的输入,
Refile
将抛出以下异常:

Errno::ENOENT (No such file or directory @ rb_sysopen - thiswillnotwork):
  app/controllers/my/deals_controller.rb:17:in `create'
  appsignal (0.11.2) lib/appsignal/rack/listener.rb:13:in `call'
是否有一个选项可以忽略输入的URL无效的情况(类似于CarrierWave中的
validate\u download
选项的工作方式),理想情况下,使用我们的回退图像

我们已尝试将
raise\u errors
选项设置为
false
安装附件,但结果相同

我们的项目使用了
rails4.2.0
refile0.5.3

编辑:

我已确认此异常是一个较低级别的
SystemCallError
,来自
Kernel.open
,并且此异常类型未通过Refile解救:

rescue OpenURI::HTTPError, RuntimeError => error
  raise if error.is_a?(RuntimeError) and error.message !~ /redirection loop/
  @errors = [:download_failed]
  raise if @raise_errors
end
我正在处理一个请求重新填充以修复此问题

编辑2:

在处理此问题时,我们在
Refile
中发现了一个漏洞,使潜在的攻击者能够使用远程代码执行

refilegem有一个功能,其中将提供一个URL,并上传远程文件。这可以通过在表单中添加类似
remote\u image\u url
的字段来实现,其中
image
是附件的名称。此功能使用开放uri发出此HTTP请求,而不验证传递的uri。攻击者可以创建一个URI,在主机上执行任意shell命令


如果您使用的是
Refile
版本
0.5.0
-
0.5.3
,请升级至最新版本。升级也将解决上述问题。

在与
Refile
的维护人员交谈后,这将在下一次迭代中修复。现在,我们已经创建了以下简单的Ruby类作为解决方案

# app/services/remote_url.rb
class RemoteUrl
  def initialize(url)
    @url = url
  end

  def valid?
    URI.parse(@url).kind_of?(URI::HTTP)
  rescue URI::InvalidURIError
    false
  end
end
我在控制器中使用它,如下所示:

# app/controllers/model_controller.rb
def model_params
  sanitize_remote_url!
  params.require(:model).permit(:description, ..., :image, :remote_image_url)
end

def sanitize_remote_url!
  params[:model].delete(:remote_image_url) unless RemoteUrl.new(params[:model][:remote_image_url]).valid?
end

这是一个非常原始的方法,但是考虑到它将被修补在下一个宝石版本中,我认为这已经足够好了。 免责声明:

虽然这弥补了原始问题的编辑2中提到的一些漏洞,但攻击者仍然能够执行远程代码,如果他们能够在文件系统上创建名为http:的文件夹,就像http:///etc/passwd这样的字符串将通过URL验证一样,但是仍然通过
内核读取本地文件。打开

Gem现在已经补丁(
0.5.4
),升级是正确的解决方案