Fix command injection via Symbol arguments in net-imap.
Fixes CVE-2026-42258. Additionally, backport validation regex ATOM_SPECIALS that's needed. Backported from1eb27278a6bbd9eb7ecc92db350b24Resolves: RHEL-181808
This commit is contained in:
parent
1087f0b172
commit
f0332efed4
@ -354,6 +354,12 @@ Patch81: rubygem-erb-4.0.3.1-Fix-arbitrary-code-execution-via-deserialization-by
|
||||
# https://github.com/ruby/net-imap/commit/d16e994
|
||||
# https://github.com/ruby/net-imap/commit/6b2fda5
|
||||
Patch82: rubygem-net-imap-0.3.10-Fix-Information-disclosure-via-man-in-the-middle-attack-bypassing-TLS-CVE-2026-42246.patch
|
||||
# Fix CVE-2026-42258 IMAP Command Injection via Symbol Arguments.
|
||||
# https://github.com/ruby/net-imap/commit/1eb27278a601be1135910dae6ab6e517559a2e4a
|
||||
# https://github.com/ruby/net-imap/commit/bbd9eb7ecca506fa43b656368f7aebef8ac09182
|
||||
# Additionally, backport validation regex ATOM_SPECIALS that's needed, from
|
||||
# https://github.com/ruby/net-imap/commit/92db350b24c388d2a2104f36cac9caa49a1044df
|
||||
Patch83: rubygem-net-imap-0.4.24-Fix-IMAP-Command-Injection-via-Symbol-Arguments-CVE-2026-42258.patch
|
||||
|
||||
Requires: %{name}-libs%{?_isa} = %{version}-%{release}
|
||||
Suggests: rubypick
|
||||
@ -838,6 +844,7 @@ rm -rf ext/fiddle/libffi*
|
||||
%patch80 -p1
|
||||
%patch81 -p1
|
||||
%patch82 -p1
|
||||
%patch83 -p1
|
||||
|
||||
# Instead of adjusting patch's directory, use the following form where
|
||||
# we first enter the correct directory, this allows more general application
|
||||
@ -1624,6 +1631,8 @@ make runruby TESTRUN_SCRIPT=" \
|
||||
- Fix information disclosure via MITM attack bypassing TLS in net-imap.
|
||||
(CVE-2026-42246)
|
||||
Resolves: RHEL-181777
|
||||
- Fix command injection via Symbol arguments in net-imap. (CVE-2026-42258)
|
||||
Resolves: RHEL-181808
|
||||
|
||||
* Mon Apr 27 2026 Jarek Prokop <jprokop@redhat.com> - 3.0.7-166
|
||||
- Fix arbitrary code execution via deserialization bypass in ERB. (CVE-2026-41316)
|
||||
|
||||
@ -0,0 +1,241 @@
|
||||
From ec11376b38dbfbd1dde52d3410def338c7656170 Mon Sep 17 00:00:00 2001
|
||||
From: nick evans <nick@rubinick.dev>
|
||||
Date: Wed, 22 Apr 2026 11:25:06 -0400
|
||||
Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=8D=92=20edit=20ca72ac45:=20=E2=99=BB?=
|
||||
=?UTF-8?q?=EF=B8=8F=20Extract=20superclass=20for=20(internal)=20command?=
|
||||
=?UTF-8?q?=20data?=
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Unlike the cherry-picked commit (ca72ac45), this _only_ makes
|
||||
`CommandData` the superclass for `Literal` and `Atom`. Because those
|
||||
are the classes that will be modified by later cherry-picked commits.
|
||||
This allows those other commits to merge more cleanly, and work with
|
||||
fewer modifications.
|
||||
---
|
||||
lib/net/imap.rb | 50 +++++++++++++++++++++++++------------------------
|
||||
1 file changed, 26 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
|
||||
index 1a2afc0ea7..92ff9a0fbe 100644
|
||||
--- a/lib/net/imap.rb
|
||||
+++ b/lib/net/imap.rb
|
||||
@@ -1571,33 +1571,44 @@ def start_tls_session(params = {})
|
||||
end
|
||||
end
|
||||
|
||||
- class RawData # :nodoc:
|
||||
- def send_data(imap, tag)
|
||||
- imap.__send__(:put_string, @data)
|
||||
+ # simplistic emulation of CommandData = Data.define(:data)
|
||||
+ class CommandData # :nodoc:
|
||||
+ class << self
|
||||
+ def new(arg = nil, data: arg) super(data: data) end
|
||||
+ alias :[] :new
|
||||
end
|
||||
|
||||
- def validate
|
||||
+ def initialize(data:)
|
||||
+ @data = data
|
||||
+ freeze
|
||||
end
|
||||
|
||||
- private
|
||||
+ attr_reader :data
|
||||
|
||||
- def initialize(data)
|
||||
- @data = data
|
||||
- end
|
||||
- end
|
||||
+ def to_h(&block) block ? to_h.to_h(&block) : { data: data } end
|
||||
+ def ==(other) self.class === other && to_h == other.to_h end
|
||||
+ def eql?(other) self.class === other && to_h.eql?(other.to_h) end
|
||||
+
|
||||
+ # following class definition goes beyond the basic Data.define(:data)
|
||||
+ ##
|
||||
|
||||
- class Atom # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
- imap.__send__(:put_string, @data)
|
||||
+ raise NoMethodError, "#{self.class} must implement #{__method__}"
|
||||
end
|
||||
|
||||
def validate
|
||||
end
|
||||
+ end
|
||||
|
||||
- private
|
||||
+ class RawData < CommandData # :nodoc:
|
||||
+ def send_data(imap, tag)
|
||||
+ imap.__send__(:put_string, @data)
|
||||
+ end
|
||||
+ end
|
||||
|
||||
- def initialize(data)
|
||||
- @data = data
|
||||
+ class Atom < CommandData # :nodoc:
|
||||
+ def send_data(imap, tag)
|
||||
+ imap.__send__(:put_string, @data)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1616,19 +1627,10 @@ def initialize(data)
|
||||
end
|
||||
end
|
||||
|
||||
- class Literal # :nodoc:
|
||||
+ class Literal < CommandData # :nodoc:
|
||||
def send_data(imap, tag)
|
||||
imap.__send__(:send_literal, @data, tag)
|
||||
end
|
||||
-
|
||||
- def validate
|
||||
- end
|
||||
-
|
||||
- private
|
||||
-
|
||||
- def initialize(data)
|
||||
- @data = data
|
||||
- end
|
||||
end
|
||||
|
||||
class MessageSet # :nodoc:
|
||||
|
||||
From f793ce76e5f417c011a437418feb8378039e4a37 Mon Sep 17 00:00:00 2001
|
||||
From: nick evans <nick@rubinick.dev>
|
||||
Date: Thu, 19 Feb 2026 15:06:08 -0500
|
||||
Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=8D=92=20pick=209db3e9d60:=20?=
|
||||
=?UTF-8?q?=F0=9F=A5=85=20Strictly=20validate=20symbol=20(\flag)=20argumen?=
|
||||
=?UTF-8?q?ts=20[backports=20#657]?=
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Flags should not allow `atom-specials`.
|
||||
|
||||
Previously, no validation was done on symbol data. Sending atom or flag
|
||||
args which contain atom specials could lead to various errors.
|
||||
|
||||
Although this could theoretically include injection attacks, this is not
|
||||
considered to be a critical vulnerability in `net-imap`, for the
|
||||
following reason: Valid "system flag" inputs are restricted to an
|
||||
enumerated set of RFC-defined flag types. User-defined "keyword" flags
|
||||
are sent as atoms, not flags, which use string inputs (strings which
|
||||
can't be sent as an atom will be quoted or sent as a literal). `\Seen`
|
||||
as a flag (symbol argument) is semantically different from `Seen` as a
|
||||
keyword (string argument). So there is no scenario where it is
|
||||
appropriate to call `#to_sym` on unvetted user input. Any code which
|
||||
calls `#to_sym` indiscriminately on user-input is already buggy.
|
||||
|
||||
Nevertheless, users should reasonably be able to rely on `net-imap` to
|
||||
do very basic input validation on its basic input types.
|
||||
---
|
||||
lib/net/imap.rb | 33 +++++++++++++++++++++++++++------
|
||||
1 file changed, 27 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
|
||||
index 92ff9a0fbe..5dc0638e2f 100644
|
||||
--- a/lib/net/imap.rb
|
||||
+++ b/lib/net/imap.rb
|
||||
@@ -1349,6 +1349,7 @@ def validate_data(data)
|
||||
end
|
||||
when Time
|
||||
when Symbol
|
||||
+ Flag.validate(data)
|
||||
else
|
||||
data.validate
|
||||
end
|
||||
@@ -1367,7 +1368,7 @@ def send_data(data, tag = nil)
|
||||
when Time
|
||||
send_time_data(data)
|
||||
when Symbol
|
||||
- send_symbol_data(data)
|
||||
+ Flag[data].send_data(self, tag)
|
||||
else
|
||||
data.send_data(self, tag)
|
||||
end
|
||||
@@ -1437,10 +1438,6 @@ def send_time_data(time)
|
||||
put_string(s)
|
||||
end
|
||||
|
||||
- def send_symbol_data(symbol)
|
||||
- put_string("\\" + symbol.to_s)
|
||||
- end
|
||||
-
|
||||
def search_internal(cmd, keys, charset)
|
||||
if keys.instance_of?(String)
|
||||
keys = [RawData.new(keys)]
|
||||
@@ -1592,6 +1589,12 @@ def eql?(other) self.class === other && to_h.eql?(other.to_h) end
|
||||
# following class definition goes beyond the basic Data.define(:data)
|
||||
##
|
||||
|
||||
+ def self.validate(...)
|
||||
+ data = new(...)
|
||||
+ data.validate
|
||||
+ data
|
||||
+ end
|
||||
+
|
||||
def send_data(imap, tag)
|
||||
raise NoMethodError, "#{self.class} must implement #{__method__}"
|
||||
end
|
||||
@@ -1607,8 +1610,26 @@ def send_data(imap, tag)
|
||||
end
|
||||
|
||||
class Atom < CommandData # :nodoc:
|
||||
+ def initialize(**)
|
||||
+ super
|
||||
+ validate
|
||||
+ end
|
||||
+
|
||||
+ def validate
|
||||
+ data.to_s.ascii_only? \
|
||||
+ or raise DataFormatError, "#{self.class} must be ASCII only"
|
||||
+ data.match?(ResponseParser::Patterns::ATOM_SPECIALS) \
|
||||
+ and raise DataFormatError, "#{self.class} must not contain atom-specials"
|
||||
+ end
|
||||
+
|
||||
def send_data(imap, tag)
|
||||
- imap.__send__(:put_string, @data)
|
||||
+ imap.__send__(:put_string, data.to_s)
|
||||
+ end
|
||||
+ end
|
||||
+
|
||||
+ class Flag < Atom # :nodoc:
|
||||
+ def send_data(imap, tag)
|
||||
+ imap.__send__(:put_string, "\\#{data}")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
From e407aa69f28b71f20eb83145be14ff8a2e57436f Mon Sep 17 00:00:00 2001
|
||||
From: Jarek Prokop <jprokop@redhat.com>
|
||||
Date: Tue, 9 Jun 2026 18:14:51 +0200
|
||||
Subject: [PATCH 3/3] Cherry-pick ATOM_SPECIALS for validation regex.
|
||||
|
||||
The previous commit relies on ResponseParsers::Patterns::ATOM_SPECIALS
|
||||
to be available. We could either hardcode the regex in the line where
|
||||
the matching happens, but instead have it live in its own constant for
|
||||
easier reference and less edits to the actual commit backport.
|
||||
|
||||
The line ported from:
|
||||
https://github.com/ruby/net-imap/commit/92db350b24c388d2a2104f36cac9caa49a1044df
|
||||
---
|
||||
lib/net/imap.rb | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
|
||||
index 5dc0638e2f..07af17c008 100644
|
||||
--- a/lib/net/imap.rb
|
||||
+++ b/lib/net/imap.rb
|
||||
@@ -2222,6 +2222,10 @@ def multipart?
|
||||
end
|
||||
|
||||
class ResponseParser # :nodoc:
|
||||
+ module Patterns
|
||||
+ ATOM_SPECIALS = /[(){ \x00-\x1f\x7f%*"\\\]]/n
|
||||
+ end
|
||||
+
|
||||
def initialize
|
||||
@str = nil
|
||||
@pos = nil
|
||||
Loading…
Reference in New Issue
Block a user