Skip to content

Commit 4cd5081

Browse files
committed
Don't allow remote shell execution
Kernel#open accepts a string of format "| <shell command>" 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.
1 parent 152d33a commit 4cd5081

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

Diff for: lib/mini_magick/image.rb

+6-8
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,15 @@ def self.import_pixels(blob, columns, rows, depth, map, format = 'png')
8282
def self.open(path_or_url, ext = nil, options = {})
8383
options, ext = ext, nil if ext.is_a?(Hash)
8484

85-
ext ||=
86-
if File.exist?(path_or_url)
87-
File.extname(path_or_url)
88-
else
89-
File.extname(URI(path_or_url).path)
90-
end
85+
uri = URI(path_or_url.to_s)
9186

87+
ext ||= File.extname(uri.path)
9288
ext.sub!(/:.*/, '') # hack for filenames or URLs that include a colon
9389

94-
Kernel.open(path_or_url, "rb", options) do |file|
95-
read(file, ext)
90+
if uri.is_a?(URI::HTTP) || uri.is_a?(URI::FTP)
91+
uri.open(options) { |file| read(file, ext) }
92+
else
93+
File.open(uri.to_s, "rb", options) { |file| read(file, ext) }
9694
end
9795
end
9896

Diff for: spec/lib/mini_magick/image_spec.rb

+8
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@
7676
expect(File.extname(image.path)).to eq ".jpg"
7777
end
7878

79+
it "doesn't allow remote shell execution" do
80+
expect {
81+
described_class.open("| touch file.txt") # Kernel#open accepts this
82+
}.to raise_error(URI::InvalidURIError)
83+
84+
expect(File.exist?("file.txt")).to eq(false)
85+
end
86+
7987
it "accepts open-uri options" do
8088
stub_request(:get, "http://example.com/image.jpg")
8189
.with(headers: {"Foo" => "Bar"})

0 commit comments

Comments
 (0)