Skip to content

Commit 9b251b6

Browse files
committed
Merge rexml-expansion-fix gem into activesupport.
Addresses the security issue documented at: * http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/
1 parent 79c3f73 commit 9b251b6

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
require 'rexml/document'
2+
require 'rexml/entity'
3+
4+
# Fixes the rexml vulnerability disclosed at:
5+
# http://www.ruby-lang.org/en/news/2008/08/23/dos-vulnerability-in-rexml/
6+
# This fix is identical to rexml-expansion-fix version 1.0.1
7+
8+
unless REXML::VERSION > "3.1.7.2"
9+
module REXML
10+
class Entity < Child
11+
undef_method :unnormalized
12+
def unnormalized
13+
document.record_entity_expansion! if document
14+
v = value()
15+
return nil if v.nil?
16+
@unnormalized = Text::unnormalize(v, parent)
17+
@unnormalized
18+
end
19+
end
20+
class Document < Element
21+
@@entity_expansion_limit = 10_000
22+
def self.entity_expansion_limit= val
23+
@@entity_expansion_limit = val
24+
end
25+
26+
def record_entity_expansion!
27+
@number_of_expansions ||= 0
28+
@number_of_expansions += 1
29+
if @number_of_expansions > @@entity_expansion_limit
30+
raise "Number of entity expansions exceeded, processing aborted."
31+
end
32+
end
33+
end
34+
end
35+
end

activesupport/test/core_ext/hash_ext_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,27 @@ def test_array_values_are_not_sorted
742742
:person => {:id => [20, 10]}
743743
end
744744

745+
def test_expansion_count_is_limited
746+
assert_raises RuntimeError do
747+
attack_xml = <<-EOT
748+
<?xml version="1.0" encoding="UTF-8"?>
749+
<!DOCTYPE member [
750+
<!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
751+
<!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
752+
<!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
753+
<!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
754+
<!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
755+
<!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
756+
<!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
757+
]>
758+
<member>
759+
&a;
760+
</member>
761+
EOT
762+
Hash.from_xml(attack_xml)
763+
end
764+
end
765+
745766
private
746767
def assert_query_equal(expected, actual, message = nil)
747768
assert_equal expected.split('&'), actual.to_query.split('&')

0 commit comments

Comments
 (0)