Skip to content

Commit 387116f

Browse files
committed
Fix Code Injection vulnerability in CarrierWave::RMagick
Refs. GHSA-cf3w-g86h-35x4
1 parent 012702e commit 387116f

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

lib/carrierwave/processing/rmagick.rb

+9-3
Original file line numberDiff line numberDiff line change
@@ -378,9 +378,15 @@ def manipulate!(options={}, &block)
378378

379379
def create_info_block(options)
380380
return nil unless options
381-
assignments = options.map { |k, v| "img.#{k} = #{v}" }
382-
code = "lambda { |img| " + assignments.join(";") + "}"
383-
eval code
381+
proc do |img|
382+
options.each do |k, v|
383+
if v.is_a?(String) && (matches = v.match(/^["'](.+)["']/))
384+
ActiveSupport::Deprecation.warn "Passing quoted strings like #{v} to #manipulate! is deprecated, pass them without quoting."
385+
v = matches[1]
386+
end
387+
img.public_send(:"#{k}=", v)
388+
end
389+
end
384390
end
385391

386392
def destroy_image(image)

spec/processing/rmagick_spec.rb

+33-1
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,41 @@
208208

209209
instance.manipulate! :read => {
210210
:density => 10,
211-
:size => %{"200x200"}
211+
:size => "200x200"
212212
}
213213
end
214+
215+
it 'shows deprecation but still accepts strings enclosed with double quotes' do
216+
expect_any_instance_of(::Magick::Image::Info).to receive(:size=).once.with("200x200")
217+
expect(ActiveSupport::Deprecation).to receive(:warn).with(any_args)
218+
instance.manipulate! :read => {:size => %{"200x200"}}
219+
end
220+
221+
it 'shows deprecation but still accepts strings enclosed with single quotes' do
222+
expect_any_instance_of(::Magick::Image::Info).to receive(:size=).once.with("200x200")
223+
expect(ActiveSupport::Deprecation).to receive(:warn).with(any_args)
224+
instance.manipulate! :read => {:size => %{'200x200'}}
225+
end
226+
227+
it 'does not allow arbitrary code execution' do
228+
expect_any_instance_of(Kernel).not_to receive(:puts)
229+
expect do
230+
instance.manipulate! :read => {
231+
:density => "1 }; raise; {"
232+
}
233+
end.to raise_error ArgumentError, /invalid density geometry/
234+
end
235+
236+
it 'does not allow invocation of non-public methods' do
237+
module Kernel
238+
private def foo=(value); raise; end
239+
end
240+
expect do
241+
instance.manipulate! :read => {
242+
:foo => "1"
243+
}
244+
end.to raise_error NoMethodError, /private method `foo=' called/
245+
end
214246
end
215247

216248
describe "#width and #height" do

0 commit comments

Comments
 (0)