diff --git a/ruby.spec b/ruby.spec index c684a6d..0b7cde0 100644 --- a/ruby.spec +++ b/ruby.spec @@ -336,6 +336,9 @@ Patch75: rubygem-irb-1.4.2-Fix-already-initialized-constant-messages-from-requir # Fix Denial of Service in CGI::Cookie.parse. (CVE-2025-27219) # https://github.com/ruby/cgi/commit/2f8ec73bb3eb71c4cf13e735f2d696603de2f34b Patch76: rubygem-cgi-0.3.5.1-Fix-DoS-in-CGI-Cookie-parse-CVE-2025-27219.patch +# Fix ReDoS in CGI::Util#escapeElement. (CVE-2025-27220) +# https://github.com/ruby/cgi/commit/bfa69e120df4e0131bb05df6c5e05c1dc982cd37 +Patch77: rubygem-cgi-0.3.5.1-Fix-ReDoS-in-CGI-CVE-2025-27220.patch Requires: %{name}-libs%{?_isa} = %{version}-%{release} Suggests: rubypick @@ -814,6 +817,7 @@ rm -rf ext/fiddle/libffi* %patch74 -p1 %patch75 -p1 %patch76 -p1 +%patch77 -p1 # Instead of adjusting patch's directory, use the following form where # we first enter the correct directory, this allows more general application @@ -1599,6 +1603,8 @@ make runruby TESTRUN_SCRIPT=" \ * Fri Apr 11 2025 Jarek Prokop - 3.0.7-165 - Fix Denial of Service in CGI::Cookie.parse. (CVE-2025-27219) Resolves: RHEL-86104 +- Fix ReDoS in CGI::Util#escapeElement. (CVE-2025-27220) + Resolves: RHEL-86130 * Thu Mar 06 2025 Jarek Prokop - 3.0.7-164 - Undefine GC compaction methods on ppc64le. diff --git a/rubygem-cgi-0.3.5.1-Fix-ReDoS-in-CGI-CVE-2025-27220.patch b/rubygem-cgi-0.3.5.1-Fix-ReDoS-in-CGI-CVE-2025-27220.patch new file mode 100644 index 0000000..a7fdb00 --- /dev/null +++ b/rubygem-cgi-0.3.5.1-Fix-ReDoS-in-CGI-CVE-2025-27220.patch @@ -0,0 +1,68 @@ +From 725d6f699f589d9b5454e189d33292027532984d Mon Sep 17 00:00:00 2001 +From: Hiroshi SHIBATA +Date: Fri, 21 Feb 2025 15:53:31 +0900 +Subject: [PATCH] Escape/unescape unclosed tags as well + +Co-authored-by: Nobuyoshi Nakada +--- + lib/cgi/util.rb | 4 ++-- + test/cgi/test_cgi_util.rb | 18 ++++++++++++++++++ + 2 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/lib/cgi/util.rb b/lib/cgi/util.rb +index aab8b000cb..5ff8ba58eb 100644 +--- a/lib/cgi/util.rb ++++ b/lib/cgi/util.rb +@@ -140,7 +140,7 @@ def unescapeHTML(string) + def escapeElement(string, *elements) + elements = elements[0] if elements[0].kind_of?(Array) + unless elements.empty? +- string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i) do ++ string.gsub(/<\/?(?:#{elements.join("|")})\b[^<>]*+>?/im) do + CGI.escapeHTML($&) + end + else +@@ -160,7 +160,7 @@ def escapeElement(string, *elements) + def unescapeElement(string, *elements) + elements = elements[0] if elements[0].kind_of?(Array) + unless elements.empty? +- string.gsub(/<\/?(?:#{elements.join("|")})(?!\w)(?:.|\n)*?>/i) do ++ string.gsub(/<\/?(?:#{elements.join("|")})\b(?>[^&]+|&(?![gl]t;)\w+;)*(?:>)?/im) do + unescapeHTML($&) + end + else +diff --git a/test/cgi/test_cgi_util.rb b/test/cgi/test_cgi_util.rb +index b7bb7b8eae..e93be474b3 100644 +--- a/test/cgi/test_cgi_util.rb ++++ b/test/cgi/test_cgi_util.rb +@@ -181,6 +181,14 @@ def test_cgi_escapeElement + assert_equal("
<A HREF="url"></A>", escapeElement('
', ["A", "IMG"])) + assert_equal("
<A HREF="url"></A>", escape_element('
', "A", "IMG")) + assert_equal("
<A HREF="url"></A>", escape_element('
', ["A", "IMG"])) ++ ++ assert_equal("<A <A HREF="url"></A>", escapeElement('', "A", "IMG")) ++ assert_equal("<A <A HREF="url"></A>", escapeElement('', ["A", "IMG"])) ++ assert_equal("<A <A HREF="url"></A>", escape_element('', "A", "IMG")) ++ assert_equal("<A <A HREF="url"></A>", escape_element('', ["A", "IMG"])) ++ ++ assert_equal("<A <A ", escapeElement('', unescapeElement(escapeHTML('
'), ["A", "IMG"])) + assert_equal('<BR>', unescape_element(escapeHTML('
'), "A", "IMG")) + assert_equal('<BR>', unescape_element(escapeHTML('
'), ["A", "IMG"])) ++ ++ assert_equal('', unescapeElement(escapeHTML(''), "A", "IMG")) ++ assert_equal('', unescapeElement(escapeHTML(''), ["A", "IMG"])) ++ assert_equal('', unescape_element(escapeHTML(''), "A", "IMG")) ++ assert_equal('', unescape_element(escapeHTML(''), ["A", "IMG"])) ++ ++ assert_equal('