image_processing 2.0.2 → 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 +6 -0
- data/lib/image_processing/chainable.rb +11 -12
- data/lib/image_processing/mini_magick.rb +7 -0
- data/lib/image_processing/processor.rb +9 -0
- data/lib/image_processing/version.rb +1 -1
- data/lib/image_processing.rb +19 -0
- metadata +2 -2
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,9 @@
|
|
|
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
|
+
|
|
1
7
|
## 2.0.2 (2026-06-03)
|
|
2
8
|
|
|
3
9
|
* Raise `LoadError` instead of `ImageProcessing::Error` when soft dependencies are missing (@bdewater-thatch)
|
|
@@ -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 = {
|
|
@@ -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)
|
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ć
|
|
@@ -105,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
105
105
|
- !ruby/object:Gem::Version
|
|
106
106
|
version: '0'
|
|
107
107
|
requirements: []
|
|
108
|
-
rubygems_version: 4.0.
|
|
108
|
+
rubygems_version: 4.0.13
|
|
109
109
|
specification_version: 4
|
|
110
110
|
summary: High-level wrapper for processing images for the web with ImageMagick or
|
|
111
111
|
libvips.
|