diff --git a/CVE-2019-13574-1.patch b/CVE-2019-13574-1.patch new file mode 100644 index 0000000..7efc847 --- /dev/null +++ b/CVE-2019-13574-1.patch @@ -0,0 +1,47 @@ +From 4cd5081e58810d3394d27a67219e8e4e0445d851 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Janko=20Marohni=C4=87?= +Date: Sun, 26 May 2019 17:30:14 +0200 +Subject: [PATCH] Don't allow remote shell execution + +Kernel#open accepts a string of format "| " which +executes the specified shell command and otherwise presumably acts as +IO.popen. The open-uri standard library overrides Kernel#open to also +accept URLs. + +However, the overridden Kernel#open just delegates to URI#open, so we +switch to using that directly and avoid the remote shell execution +vulnerability. For files we just use File.open, which should have the +same behaviour as Kernel#open. +--- + lib/mini_magick/image.rb | 14 ++++++-------- + spec/lib/mini_magick/image_spec.rb | 8 ++++++++ + 2 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/lib/mini_magick/image.rb b/lib/mini_magick/image.rb +index a1f47c6..0ac4780 100644 +--- a/lib/mini_magick/image.rb ++++ b/lib/mini_magick/image.rb +@@ -82,17 +82,15 @@ def self.import_pixels(blob, columns, rows, depth, map, format = 'png') + def self.open(path_or_url, ext = nil, options = {}) + options, ext = ext, nil if ext.is_a?(Hash) + +- ext ||= +- if File.exist?(path_or_url) +- File.extname(path_or_url) +- else +- File.extname(URI(path_or_url).path) +- end ++ uri = URI(path_or_url.to_s) + ++ ext ||= File.extname(uri.path) + ext.sub!(/:.*/, '') # hack for filenames or URLs that include a colon + +- Kernel.open(path_or_url, "rb", options) do |file| +- read(file, ext) ++ if uri.is_a?(URI::HTTP) || uri.is_a?(URI::FTP) ++ uri.open(options) { |file| read(file, ext) } ++ else ++ File.open(uri.to_s, "rb", options) { |file| read(file, ext) } + end + end + diff --git a/CVE-2019-13574-2.patch b/CVE-2019-13574-2.patch new file mode 100644 index 0000000..4ba4df9 --- /dev/null +++ b/CVE-2019-13574-2.patch @@ -0,0 +1,66 @@ +From 4cd5081e58810d3394d27a67219e8e4e0445d851 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Janko=20Marohni=C4=87?= +Date: Sun, 26 May 2019 17:30:14 +0200 +Subject: [PATCH] Don't allow remote shell execution + +Kernel#open accepts a string of format "| " which +executes the specified shell command and otherwise presumably acts as +IO.popen. The open-uri standard library overrides Kernel#open to also +accept URLs. + +However, the overridden Kernel#open just delegates to URI#open, so we +switch to using that directly and avoid the remote shell execution +vulnerability. For files we just use File.open, which should have the +same behaviour as Kernel#open. +--- + lib/mini_magick/image.rb | 14 ++++++-------- + spec/lib/mini_magick/image_spec.rb | 8 ++++++++ + 2 files changed, 14 insertions(+), 8 deletions(-) + +diff --git a/lib/mini_magick/image.rb b/lib/mini_magick/image.rb +index a1f47c6..0ac4780 100644 +--- a/lib/mini_magick/image.rb ++++ b/lib/mini_magick/image.rb +@@ -82,17 +82,15 @@ def self.import_pixels(blob, columns, rows, depth, map, format = 'png') + def self.open(path_or_url, ext = nil, options = {}) + options, ext = ext, nil if ext.is_a?(Hash) + +- ext ||= +- if File.exist?(path_or_url) +- File.extname(path_or_url) +- else +- File.extname(URI(path_or_url).path) +- end ++ uri = URI(path_or_url.to_s) + ++ ext ||= File.extname(uri.path) + ext.sub!(/:.*/, '') # hack for filenames or URLs that include a colon + +- Kernel.open(path_or_url, "rb", options) do |file| +- read(file, ext) ++ if uri.is_a?(URI::HTTP) || uri.is_a?(URI::FTP) ++ uri.open(options) { |file| read(file, ext) } ++ else ++ File.open(uri.to_s, "rb", options) { |file| read(file, ext) } + end + end + +diff --git a/spec/lib/mini_magick/image_spec.rb b/spec/lib/mini_magick/image_spec.rb +index 192d834..00f9cb0 100644 +--- a/spec/lib/mini_magick/image_spec.rb ++++ b/spec/lib/mini_magick/image_spec.rb +@@ -76,6 +76,14 @@ + expect(File.extname(image.path)).to eq ".jpg" + end + ++ it "doesn't allow remote shell execution" do ++ expect { ++ described_class.open("| touch file.txt") # Kernel#open accepts this ++ }.to raise_error(URI::InvalidURIError) ++ ++ expect(File.exist?("file.txt")).to eq(false) ++ end ++ + it "accepts open-uri options" do + stub_request(:get, "http://example.com/image.jpg") + .with(headers: {"Foo" => "Bar"}) diff --git a/rubygem-mini_magick.spec b/rubygem-mini_magick.spec index ff0a1e2..ab33cde 100644 --- a/rubygem-mini_magick.spec +++ b/rubygem-mini_magick.spec @@ -1,7 +1,7 @@ %global gem_name mini_magick Name: rubygem-%{gem_name} Version: 4.8.0 -Release: 2 +Release: 3 Summary: Manipulate images with minimal use of memory via ImageMagick License: MIT URL: https://github.com/minimagick/minimagick @@ -13,6 +13,8 @@ Patch0: mini_magick-4.8.0-Use-smallcase-for-Image-details-in-tests. # Match new `identify` error message # https://github.com/minimagick/minimagick/pull/455/ Patch1: mini_magick-4.8.0-match-new-identify-error-message-in-tests.patch +Patch2: CVE-2019-13574-1.patch +Patch3: CVE-2019-13574-2.patch Requires: ImageMagick BuildRequires: ruby(release) rubygems-devel ruby rubygem(rspec) rubygem(webmock) ImageMagick BuildArch: noarch @@ -31,6 +33,7 @@ Documentation for %{name}. %prep %setup -q -n %{gem_name}-%{version} +%patch2 -p1 %build gem build ../%{gem_name}-%{version}.gemspec @@ -47,6 +50,7 @@ tar xzvf %{SOURCE1} cd minimagick-%{version} cat %{PATCH0} | patch -p1 cat %{PATCH1} | patch -p1 +cat %{PATCH3} | patch -p1 sed -i -e '/require "pry"/ s/^/#/g' \ -e '/require "bundler/ s/^/#/g' \ spec/spec_helper.rb @@ -72,6 +76,9 @@ popd %{gem_instdir}/Rakefile %changelog +* Tue Apr 13 2021 wangxiao65 - 1.0.2-3 +- Fix CVE-2019-13574 + * Tue Sep 8 2020 yanan li - 1.0.2-2 - fix build fail