image_processing 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/image_processing.gemspec +0 -1
- data/lib/image_processing/chainable.rb +11 -12
- data/lib/image_processing/mini_magick.rb +8 -1
- data/lib/image_processing/processor.rb +9 -0
- data/lib/image_processing/version.rb +1 -1
- data/lib/image_processing/vips.rb +1 -1
- data/lib/image_processing.rb +19 -0
- metadata +2 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 073bdcd7bc5e6fbb52b92f70de43d3b700316620dd23ec75b9aeac18bd5375b3
|
|
4
|
+
data.tar.gz: 1678df6fd73afc2230fafd9c3f84b2d5174351819ef0f3961ed5206f2c6ae53b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e41739ac97beb0cb48cd97be766578cac1c14b4fd86fea0dd7401b835ecfbd2c018485d12ea0cb6d3c6cfcf0d4e0355d5c011770dd7f0c74aec26e7499cb306f
|
|
7
|
+
data.tar.gz: 7618aa5091de6ddc2a01a189e548e508d862535ad8a7f4e400845c8696fcace78081f33efc343fa220ed04d13a0a71106a7e7c10141c107764270640ad30a0a6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 2.0.3 (2026-06-08)
|
|
2
|
+
|
|
3
|
+
* Prevent remote code execution when operation names come from user input, closing bypasses through the `#operation` meta-builder, `#method_missing`, and nested `#send` calls (reported by @szymonsec)
|
|
4
|
+
|
|
5
|
+
* [minimagick] Prevent remote code execution through unsafe public methods (e.g. `#instance_eval`, `#send`) passed as loader/saver option names
|
|
6
|
+
|
|
7
|
+
## 2.0.2 (2026-06-03)
|
|
8
|
+
|
|
9
|
+
* Raise `LoadError` instead of `ImageProcessing::Error` when soft dependencies are missing (@bdewater-thatch)
|
|
10
|
+
|
|
1
11
|
## 2.0.1 (2026-05-22)
|
|
2
12
|
|
|
3
13
|
* [minimagick] Prevent remote shell execution when passing loader/saver options from user input
|
data/image_processing.gemspec
CHANGED
|
@@ -23,5 +23,4 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
spec.add_development_dependency "minitest", "~> 5.8"
|
|
24
24
|
spec.add_development_dependency "minitest-hooks", ">= 1.4.2"
|
|
25
25
|
spec.add_development_dependency "minispec-metadata"
|
|
26
|
-
spec.add_development_dependency "dhash-vips" unless RUBY_ENGINE == "jruby"
|
|
27
26
|
end
|
|
@@ -86,25 +86,24 @@ module ImageProcessing
|
|
|
86
86
|
private
|
|
87
87
|
|
|
88
88
|
# This prevents calling unsafe Ruby core methods such as `Kernel#system`,
|
|
89
|
-
# which would allow for remote shell execution.
|
|
89
|
+
# which would allow for remote shell execution. The processor enforces the
|
|
90
|
+
# same guard when operations are dispatched, which also covers paths that
|
|
91
|
+
# bypass this early check (e.g. the #operation meta-builder).
|
|
92
|
+
#
|
|
93
|
+
# Bang names are rejected here because they are Chainable's execution
|
|
94
|
+
# shortcut (see #method_missing), not operations to chain.
|
|
90
95
|
def invalid_operation?(name)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
owner = method(name).owner
|
|
94
|
-
[BasicObject, Kernel, Object, Module].include?(owner)
|
|
95
|
-
rescue NameError
|
|
96
|
-
false
|
|
96
|
+
name.end_with?("!") || ImageProcessing.unsafe_method?(self, name)
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
# Assume that any unknown method names an operation supported by the
|
|
100
100
|
# processor. Add a bang ("!") if you want processing to be performed.
|
|
101
|
-
def method_missing(name,
|
|
102
|
-
return super if name.
|
|
103
|
-
return public_send(name.to_s.chomp("!"),
|
|
101
|
+
def method_missing(name, ...)
|
|
102
|
+
return super if name.end_with?("?")
|
|
103
|
+
return public_send(name.to_s.chomp("!"), ...).call if name.end_with?("!")
|
|
104
104
|
|
|
105
|
-
operation(name,
|
|
105
|
+
operation(name, ...)
|
|
106
106
|
end
|
|
107
|
-
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
|
108
107
|
|
|
109
108
|
# Empty options which the builder starts with.
|
|
110
109
|
DEFAULT_OPTIONS = {
|
|
@@ -2,7 +2,7 @@ require "image_processing"
|
|
|
2
2
|
begin
|
|
3
3
|
require "mini_magick"
|
|
4
4
|
rescue LoadError
|
|
5
|
-
|
|
5
|
+
raise LoadError, "ImageProcessing::MiniMagick requires the mini_magick gem. Please add `gem \"mini_magick\", \"~> 5.0\"` to your Gemfile."
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
module ImageProcessing
|
|
@@ -225,6 +225,13 @@ module ImageProcessing
|
|
|
225
225
|
# Applies options from the provided hash.
|
|
226
226
|
def apply_options(magick, define: {}, **options)
|
|
227
227
|
options.each do |option, value|
|
|
228
|
+
# Loader/saver option names may come from user input, so guard
|
|
229
|
+
# against dispatching to unsafe Ruby core methods (e.g. #send,
|
|
230
|
+
# #instance_eval) that public_send does not block on its own.
|
|
231
|
+
if ImageProcessing.unsafe_method?(magick, option)
|
|
232
|
+
raise Error, "#{option.inspect} is not a valid option"
|
|
233
|
+
end
|
|
234
|
+
|
|
228
235
|
case value
|
|
229
236
|
when true, nil then magick.public_send(option)
|
|
230
237
|
when false then magick.public_send(option).+
|
|
@@ -53,6 +53,15 @@ module ImageProcessing
|
|
|
53
53
|
# operation directly on the accumulator object. This provides a common
|
|
54
54
|
# umbrella above defined macros and direct operations.
|
|
55
55
|
def apply_operation(name, *args, &block)
|
|
56
|
+
# Chainable performs the same check when operations are built, but that
|
|
57
|
+
# guard only sees the outer builder method name, so it can be routed
|
|
58
|
+
# around via the #operation meta-builder, #method_missing, or a nested
|
|
59
|
+
# #send. This is the single point every operation is finally dispatched
|
|
60
|
+
# through, so enforcing the guard here closes all of those paths.
|
|
61
|
+
if ImageProcessing.unsafe_method?(self, name)
|
|
62
|
+
fail Error, "#{name.inspect} is not a valid operation"
|
|
63
|
+
end
|
|
64
|
+
|
|
56
65
|
receiver = respond_to?(name) ? self : @accumulator
|
|
57
66
|
|
|
58
67
|
if args.last.is_a?(Hash)
|
|
@@ -2,7 +2,7 @@ require "image_processing"
|
|
|
2
2
|
begin
|
|
3
3
|
require "vips"
|
|
4
4
|
rescue LoadError
|
|
5
|
-
|
|
5
|
+
raise LoadError, "ImageProcessing::Vips requires the ruby-vips gem. Please add `gem \"ruby-vips\", \"~> 2.0\"` to your Gemfile."
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
Vips.block_untrusted(true) if Vips.respond_to?(:block_untrusted) && !ENV["VIPS_BLOCK_UNTRUSTED"]
|
data/lib/image_processing.rb
CHANGED
|
@@ -7,6 +7,25 @@ require "image_processing/version"
|
|
|
7
7
|
module ImageProcessing
|
|
8
8
|
Error = Class.new(StandardError)
|
|
9
9
|
|
|
10
|
+
# Method owners considered unsafe to dispatch to when a method name comes
|
|
11
|
+
# from user input, because they expose Ruby's metaprogramming and shell
|
|
12
|
+
# primitives (e.g. Kernel#send, Kernel#eval, BasicObject#instance_eval,
|
|
13
|
+
# Kernel#system). Any name whose implementation is inherited from one of
|
|
14
|
+
# these should never be treated as an image operation or a loader/saver
|
|
15
|
+
# option.
|
|
16
|
+
UNSAFE_METHOD_OWNERS = [BasicObject, Kernel, Object, Module].freeze
|
|
17
|
+
|
|
18
|
+
# Whether calling +name+ on +receiver+ would dispatch to an unsafe Ruby core
|
|
19
|
+
# method rather than a genuine operation. Used as a single, shared guard at
|
|
20
|
+
# every place where a user-provided name is dispatched via +public_send+.
|
|
21
|
+
def self.unsafe_method?(receiver, name)
|
|
22
|
+
UNSAFE_METHOD_OWNERS.include?(receiver.method(name.to_s).owner)
|
|
23
|
+
rescue NameError
|
|
24
|
+
# An unknown name is not a Ruby core method, so it is safe to forward to
|
|
25
|
+
# the receiver (which will reject it if it is not a real operation).
|
|
26
|
+
false
|
|
27
|
+
end
|
|
28
|
+
|
|
10
29
|
autoload :MiniMagick, "image_processing/mini_magick"
|
|
11
30
|
autoload :Vips, "image_processing/vips"
|
|
12
31
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: image_processing
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Janko Marohnić
|
|
@@ -65,20 +65,6 @@ dependencies:
|
|
|
65
65
|
- - ">="
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
67
|
version: '0'
|
|
68
|
-
- !ruby/object:Gem::Dependency
|
|
69
|
-
name: dhash-vips
|
|
70
|
-
requirement: !ruby/object:Gem::Requirement
|
|
71
|
-
requirements:
|
|
72
|
-
- - ">="
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: '0'
|
|
75
|
-
type: :development
|
|
76
|
-
prerelease: false
|
|
77
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
-
requirements:
|
|
79
|
-
- - ">="
|
|
80
|
-
- !ruby/object:Gem::Version
|
|
81
|
-
version: '0'
|
|
82
68
|
description: High-level wrapper for processing images for the web with ImageMagick
|
|
83
69
|
or libvips.
|
|
84
70
|
email:
|
|
@@ -119,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
119
105
|
- !ruby/object:Gem::Version
|
|
120
106
|
version: '0'
|
|
121
107
|
requirements: []
|
|
122
|
-
rubygems_version: 4.0.
|
|
108
|
+
rubygems_version: 4.0.13
|
|
123
109
|
specification_version: 4
|
|
124
110
|
summary: High-level wrapper for processing images for the web with ImageMagick or
|
|
125
111
|
libvips.
|