diff --git a/configs/components/ruby-2.7.8.rb b/configs/components/ruby-2.7.8.rb
index cf1df8999..794041db6 100644
--- a/configs/components/ruby-2.7.8.rb
+++ b/configs/components/ruby-2.7.8.rb
@@ -41,6 +41,8 @@
pkg.apply_patch "#{base}/regexp_use_after_free.patch"
pkg.apply_patch "#{base}/uri-redos-cve-2023-36617.patch"
+ pkg.apply_patch "#{base}/rexml_for_CVE-2024-35176.patch"
+
if platform.is_cross_compiled?
unless platform.is_macos?
diff --git a/configs/components/ruby-3.2.4.rb b/configs/components/ruby-3.2.4.rb
index b5e808a1b..6bffdcf6d 100644
--- a/configs/components/ruby-3.2.4.rb
+++ b/configs/components/ruby-3.2.4.rb
@@ -38,6 +38,9 @@
base = 'resources/patches/ruby_32'
+ #this patch is not required in ruby >= 3.2.5
+ pkg.apply_patch "#{base}/rexml_for_CVE-2024-35176.patch"
+
if platform.is_cross_compiled?
pkg.apply_patch "#{base}/rbinstall_gem_path.patch"
end
diff --git a/resources/patches/ruby_27/rexml_for_CVE-2024-35176.patch b/resources/patches/ruby_27/rexml_for_CVE-2024-35176.patch
new file mode 100644
index 000000000..e9df6fcc7
--- /dev/null
+++ b/resources/patches/ruby_27/rexml_for_CVE-2024-35176.patch
@@ -0,0 +1,135 @@
+diff --git a/Gemfile b/Gemfile
+index 042ef8ac..f78cc861 100644
+--- a/Gemfile
++++ b/Gemfile
+@@ -10,4 +10,5 @@ group :development do
+ gem "bundler"
+ gem "rake"
+ gem "test-unit"
++ gem "test-unit-ruby-core"
+ end
+diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
+index 8d62391c..d09237c5 100644
+--- a/lib/rexml/parsers/baseparser.rb
++++ b/lib/rexml/parsers/baseparser.rb
+@@ -628,17 +628,17 @@ def parse_attributes(prefixes, curr_ns)
+ message = "Missing attribute equal: <#{name}>"
+ raise REXML::ParseException.new(message, @source)
+ end
+- unless match = @source.match(/(['"])(.*?)\1\s*/um, true)
+- if match = @source.match(/(['"])/, true)
+- message =
+- "Missing attribute value end quote: <#{name}>: <#{match[1]}>"
+- raise REXML::ParseException.new(message, @source)
+- else
+- message = "Missing attribute value start quote: <#{name}>"
+- raise REXML::ParseException.new(message, @source)
+- end
++ unless match = @source.match(/(['"])/, true)
++ message = "Missing attribute value start quote: <#{name}>"
++ raise REXML::ParseException.new(message, @source)
++ end
++ quote = match[1]
++ value = @source.read_until(quote)
++ unless value.chomp!(quote)
++ message = "Missing attribute value end quote: <#{name}>: <#{quote}>"
++ raise REXML::ParseException.new(message, @source)
+ end
+- value = match[2]
++ @source.match(/\s*/um, true)
+ if prefix == "xmlns"
+ if local_part == "xml"
+ if value != "http://www.w3.org/XML/1998/namespace"
+diff --git a/lib/rexml/source.rb b/lib/rexml/source.rb
+index 7f47c2be..999751b4 100644
+--- a/lib/rexml/source.rb
++++ b/lib/rexml/source.rb
+@@ -65,7 +65,11 @@ def encoding=(enc)
+ encoding_updated
+ end
+
+- def read
++ def read(term = nil)
++ end
++
++ def read_until(term)
++ @scanner.scan_until(Regexp.union(term)) or @scanner.rest
+ end
+
+ def ensure_buffer
+@@ -158,9 +162,9 @@ def initialize(arg, block_size=500, encoding=nil)
+ end
+ end
+
+- def read
++ def read(term = nil)
+ begin
+- @scanner << readline
++ @scanner << readline(term)
+ true
+ rescue Exception, NameError
+ @source = nil
+@@ -168,6 +172,21 @@ def read
+ end
+ end
+
++ def read_until(term)
++ pattern = Regexp.union(term)
++ data = []
++ begin
++ until str = @scanner.scan_until(pattern)
++ @scanner << readline(term)
++ end
++ rescue EOFError
++ @scanner.rest
++ else
++ read if @scanner.eos? and !@source.eof?
++ str
++ end
++ end
++
+ def ensure_buffer
+ read if @scanner.eos? && @source
+ end
+@@ -218,8 +237,8 @@ def current_line
+ end
+
+ private
+- def readline
+- str = @source.readline(@line_break)
++ def readline(term = nil)
++ str = @source.readline(term || @line_break)
+ if @pending_buffer
+ if str.nil?
+ str = @pending_buffer
+diff --git a/test/test_document.rb b/test/test_document.rb
+index 953656f8..f96bfd5d 100644
+--- a/test/test_document.rb
++++ b/test/test_document.rb
+@@ -1,8 +1,12 @@
+ # -*- coding: utf-8 -*-
+ # frozen_string_literal: false
+
++require 'core_assertions'
++
+ module REXMLTests
+ class TestDocument < Test::Unit::TestCase
++ include Test::Unit::CoreAssertions
++
+ def test_version_attributes_to_s
+ doc = REXML::Document.new(<<~eoxml)
+
+@@ -198,6 +202,13 @@ def test_xml_declaration_standalone
+ assert_equal('no', doc.stand_alone?, bug2539)
+ end
+
++ def test_gt_linear_performance
++ seq = [10000, 50000, 100000, 150000, 200000]
++ assert_linear_performance(seq) do |n|
++ REXML::Document.new('" * n + '">')
++ end
++ end
++
+ class WriteTest < Test::Unit::TestCase
+ def setup
+ @document = REXML::Document.new(<<-EOX)
\ No newline at end of file
diff --git a/resources/patches/ruby_32/rexml_for_CVE-2024-35176.patch b/resources/patches/ruby_32/rexml_for_CVE-2024-35176.patch
new file mode 100644
index 000000000..e9df6fcc7
--- /dev/null
+++ b/resources/patches/ruby_32/rexml_for_CVE-2024-35176.patch
@@ -0,0 +1,135 @@
+diff --git a/Gemfile b/Gemfile
+index 042ef8ac..f78cc861 100644
+--- a/Gemfile
++++ b/Gemfile
+@@ -10,4 +10,5 @@ group :development do
+ gem "bundler"
+ gem "rake"
+ gem "test-unit"
++ gem "test-unit-ruby-core"
+ end
+diff --git a/lib/rexml/parsers/baseparser.rb b/lib/rexml/parsers/baseparser.rb
+index 8d62391c..d09237c5 100644
+--- a/lib/rexml/parsers/baseparser.rb
++++ b/lib/rexml/parsers/baseparser.rb
+@@ -628,17 +628,17 @@ def parse_attributes(prefixes, curr_ns)
+ message = "Missing attribute equal: <#{name}>"
+ raise REXML::ParseException.new(message, @source)
+ end
+- unless match = @source.match(/(['"])(.*?)\1\s*/um, true)
+- if match = @source.match(/(['"])/, true)
+- message =
+- "Missing attribute value end quote: <#{name}>: <#{match[1]}>"
+- raise REXML::ParseException.new(message, @source)
+- else
+- message = "Missing attribute value start quote: <#{name}>"
+- raise REXML::ParseException.new(message, @source)
+- end
++ unless match = @source.match(/(['"])/, true)
++ message = "Missing attribute value start quote: <#{name}>"
++ raise REXML::ParseException.new(message, @source)
++ end
++ quote = match[1]
++ value = @source.read_until(quote)
++ unless value.chomp!(quote)
++ message = "Missing attribute value end quote: <#{name}>: <#{quote}>"
++ raise REXML::ParseException.new(message, @source)
+ end
+- value = match[2]
++ @source.match(/\s*/um, true)
+ if prefix == "xmlns"
+ if local_part == "xml"
+ if value != "http://www.w3.org/XML/1998/namespace"
+diff --git a/lib/rexml/source.rb b/lib/rexml/source.rb
+index 7f47c2be..999751b4 100644
+--- a/lib/rexml/source.rb
++++ b/lib/rexml/source.rb
+@@ -65,7 +65,11 @@ def encoding=(enc)
+ encoding_updated
+ end
+
+- def read
++ def read(term = nil)
++ end
++
++ def read_until(term)
++ @scanner.scan_until(Regexp.union(term)) or @scanner.rest
+ end
+
+ def ensure_buffer
+@@ -158,9 +162,9 @@ def initialize(arg, block_size=500, encoding=nil)
+ end
+ end
+
+- def read
++ def read(term = nil)
+ begin
+- @scanner << readline
++ @scanner << readline(term)
+ true
+ rescue Exception, NameError
+ @source = nil
+@@ -168,6 +172,21 @@ def read
+ end
+ end
+
++ def read_until(term)
++ pattern = Regexp.union(term)
++ data = []
++ begin
++ until str = @scanner.scan_until(pattern)
++ @scanner << readline(term)
++ end
++ rescue EOFError
++ @scanner.rest
++ else
++ read if @scanner.eos? and !@source.eof?
++ str
++ end
++ end
++
+ def ensure_buffer
+ read if @scanner.eos? && @source
+ end
+@@ -218,8 +237,8 @@ def current_line
+ end
+
+ private
+- def readline
+- str = @source.readline(@line_break)
++ def readline(term = nil)
++ str = @source.readline(term || @line_break)
+ if @pending_buffer
+ if str.nil?
+ str = @pending_buffer
+diff --git a/test/test_document.rb b/test/test_document.rb
+index 953656f8..f96bfd5d 100644
+--- a/test/test_document.rb
++++ b/test/test_document.rb
+@@ -1,8 +1,12 @@
+ # -*- coding: utf-8 -*-
+ # frozen_string_literal: false
+
++require 'core_assertions'
++
+ module REXMLTests
+ class TestDocument < Test::Unit::TestCase
++ include Test::Unit::CoreAssertions
++
+ def test_version_attributes_to_s
+ doc = REXML::Document.new(<<~eoxml)
+
+@@ -198,6 +202,13 @@ def test_xml_declaration_standalone
+ assert_equal('no', doc.stand_alone?, bug2539)
+ end
+
++ def test_gt_linear_performance
++ seq = [10000, 50000, 100000, 150000, 200000]
++ assert_linear_performance(seq) do |n|
++ REXML::Document.new('" * n + '">')
++ end
++ end
++
+ class WriteTest < Test::Unit::TestCase
+ def setup
+ @document = REXML::Document.new(<<-EOX)
\ No newline at end of file