[rubygem-activesupport/f18] Fix for CVE-2013-0156.

Vít Ondruch vondruch at fedoraproject.org
Wed Jan 9 16:14:23 UTC 2013


commit 54a9688c64a1030321fdb68efbde3f78a55640de
Author: Vít Ondruch <vondruch at redhat.com>
Date:   Wed Jan 9 17:13:20 2013 +0100

    Fix for CVE-2013-0156.

 ...esupport-3.2.11-CVE-2013-0156-xml_parsing.patch |  160 ++++++++++++++++++++
 rubygem-activesupport.spec                         |   10 +-
 2 files changed, 169 insertions(+), 1 deletions(-)
---
diff --git a/rubygem-activesupport-3.2.11-CVE-2013-0156-xml_parsing.patch b/rubygem-activesupport-3.2.11-CVE-2013-0156-xml_parsing.patch
new file mode 100644
index 0000000..3901d9d
--- /dev/null
+++ b/rubygem-activesupport-3.2.11-CVE-2013-0156-xml_parsing.patch
@@ -0,0 +1,160 @@
+From 43109ecb986470ef023a7e91beb9812718f000fe Mon Sep 17 00:00:00 2001
+From: Jeremy Kemper <jeremy at bitsweat.net>
+Date: Sat, 5 Jan 2013 17:46:26 -0700
+Subject: [PATCH] CVE-2013-0156: Safe XML params parsing. Doesn't allow
+ symbols or yaml.
+
+---
+ .../active_support/core_ext/hash/conversions.rb    |   32 +++++++++++++++-----
+ activesupport/test/core_ext/hash_ext_test.rb       |   28 +++++++++++++----
+ 2 files changed, 47 insertions(+), 13 deletions(-)
+
+diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
+index 5f07bb4..b820a16 100644
+--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
++++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
+@@ -85,15 +85,33 @@ class Hash
+     end
+   end
+ 
++  class DisallowedType < StandardError #:nodoc:
++    def initialize(type)
++      super "Disallowed type attribute: #{type.inspect}"
++    end
++  end
++
++  DISALLOWED_XML_TYPES = %w(symbol yaml)
++
+   class << self
+-    def from_xml(xml)
+-      typecast_xml_value(unrename_keys(ActiveSupport::XmlMini.parse(xml)))
++    def from_xml(xml, disallowed_types = nil)
++      typecast_xml_value(unrename_keys(ActiveSupport::XmlMini.parse(xml)), disallowed_types)
++    end
++
++    def from_trusted_xml(xml)
++      from_xml xml, []
+     end
+ 
+     private
+-      def typecast_xml_value(value)
++      def typecast_xml_value(value, disallowed_types = nil)
++        disallowed_types ||= DISALLOWED_XML_TYPES
++
+         case value.class.to_s
+           when 'Hash'
++            if value.include?('type') && !value['type'].is_a?(Hash) && disallowed_types.include?(value['type'])
++              raise DisallowedType, value['type']
++            end
++
+             if value['type'] == 'array'
+               _, entries = Array.wrap(value.detect { |k,v| not v.is_a?(String) })
+               if entries.nil? || (c = value['__content__'] && c.blank?)
+@@ -101,9 +119,9 @@ class Hash
+               else
+                 case entries.class.to_s   # something weird with classes not matching here.  maybe singleton methods breaking is_a?
+                 when "Array"
+-                  entries.collect { |v| typecast_xml_value(v) }
++                  entries.collect { |v| typecast_xml_value(v, disallowed_types) }
+                 when "Hash"
+-                  [typecast_xml_value(entries)]
++                  [typecast_xml_value(entries, disallowed_types)]
+                 else
+                   raise "can't typecast #{entries.inspect}"
+                 end
+@@ -127,14 +145,14 @@ class Hash
+             elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash)
+               nil
+             else
+-              xml_value = Hash[value.map { |k,v| [k, typecast_xml_value(v)] }]
++              xml_value = Hash[value.map { |k,v| [k, typecast_xml_value(v, disallowed_types)] }]
+ 
+               # Turn { :files => { :file => #<StringIO> } into { :files => #<StringIO> } so it is compatible with
+               # how multipart uploaded files from HTML appear
+               xml_value["file"].is_a?(StringIO) ? xml_value["file"] : xml_value
+             end
+           when 'Array'
+-            value.map! { |i| typecast_xml_value(i) }
++            value.map! { |i| typecast_xml_value(i, disallowed_types) }
+             value.length > 1 ? value : value.first
+           when 'String'
+             value
+diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
+index b5eb049..c3a5954 100644
+--- a/activesupport/test/core_ext/hash_ext_test.rb
++++ b/activesupport/test/core_ext/hash_ext_test.rb
+@@ -733,12 +733,10 @@ class HashToXmlTest < Test::Unit::TestCase
+         <replies-close-in type="integer">2592000000</replies-close-in>
+         <written-on type="date">2003-07-16</written-on>
+         <viewed-at type="datetime">2003-07-16T09:28:00+0000</viewed-at>
+-        <content type="yaml">--- \n1: should be an integer\n:message: Have a nice day\narray: \n- should-have-dashes: true\n  should_have_underscores: true\n</content>
+         <author-email-address>david at loudthinking.com</author-email-address>
+         <parent-id></parent-id>
+         <ad-revenue type="decimal">1.5</ad-revenue>
+         <optimum-viewing-angle type="float">135</optimum-viewing-angle>
+-        <resident type="symbol">yes</resident>
+       </topic>
+     EOT
+ 
+@@ -751,12 +749,10 @@ class HashToXmlTest < Test::Unit::TestCase
+       :replies_close_in => 2592000000,
+       :written_on => Date.new(2003, 7, 16),
+       :viewed_at => Time.utc(2003, 7, 16, 9, 28),
+-      :content => { :message => "Have a nice day", 1 => "should be an integer", "array" => [{ "should-have-dashes" => true, "should_have_underscores" => true }] },
+       :author_email_address => "david at loudthinking.com",
+       :parent_id => nil,
+       :ad_revenue => BigDecimal("1.50"),
+       :optimum_viewing_angle => 135.0,
+-      :resident => :yes
+     }.stringify_keys
+ 
+     assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["topic"]
+@@ -770,7 +766,6 @@ class HashToXmlTest < Test::Unit::TestCase
+         <approved type="boolean"></approved>
+         <written-on type="date"></written-on>
+         <viewed-at type="datetime"></viewed-at>
+-        <content type="yaml"></content>
+         <parent-id></parent-id>
+       </topic>
+     EOT
+@@ -781,7 +776,6 @@ class HashToXmlTest < Test::Unit::TestCase
+       :approved   => nil,
+       :written_on => nil,
+       :viewed_at  => nil,
+-      :content    => nil,
+       :parent_id  => nil
+     }.stringify_keys
+ 
+@@ -1008,6 +1002,28 @@ class HashToXmlTest < Test::Unit::TestCase
+     assert_equal expected_product_hash, Hash.from_xml(product_xml)["product"]
+   end
+ 
++  def test_from_xml_raises_on_disallowed_type_attributes
++    assert_raise Hash::DisallowedType do
++      Hash.from_xml '<product><name type="foo">value</name></product>', %w(foo)
++    end
++  end
++
++  def test_from_xml_disallows_symbol_and_yaml_types_by_default
++    assert_raise Hash::DisallowedType do
++      Hash.from_xml '<product><name type="symbol">value</name></product>'
++    end
++
++    assert_raise Hash::DisallowedType do
++      Hash.from_xml '<product><name type="yaml">value</name></product>'
++    end
++  end
++
++  def test_from_trusted_xml_allows_symbol_and_yaml_types
++    expected = { 'product' => { 'name' => :value }}
++    assert_equal expected, Hash.from_trusted_xml('<product><name type="symbol">value</name></product>')
++    assert_equal expected, Hash.from_trusted_xml('<product><name type="yaml">:value</name></product>')
++  end
++
+   def test_should_use_default_value_for_unknown_key
+     hash_wia = HashWithIndifferentAccess.new(3)
+     assert_equal 3, hash_wia[:new_key]
+-- 
+1.7.10.2 (Apple Git-33)
+
+
diff --git a/rubygem-activesupport.spec b/rubygem-activesupport.spec
index 196bd85..0482671 100644
--- a/rubygem-activesupport.spec
+++ b/rubygem-activesupport.spec
@@ -7,7 +7,7 @@ Summary: Support and utility classes used by the Rails framework
 Name: rubygem-%{gem_name}
 Epoch: 1
 Version: 3.2.8
-Release: 1%{?dist}
+Release: 2%{?dist}
 Group: Development/Languages
 License: MIT
 URL: http://www.rubyonrails.org
@@ -35,6 +35,10 @@ Patch2: activesupport-remove-memcache-build-dep.patch
 # it under %%{gem_dir} (therefore if not in Gemfile, it won't be found).
 Patch4: activesupport-add-bigdecimal-dependency.patch
 
+# CVE-2013-0156
+# https://bugzilla.redhat.com/show_bug.cgi?id=892870
+Patch5: rubygem-activesupport-3.2.11-CVE-2013-0156-xml_parsing.patch
+
 Requires: ruby(rubygems)
 Requires: ruby(abi) = %{rubyabi}
 # Let's keep Requires and BuildRequires sorted alphabeticaly
@@ -75,6 +79,7 @@ tar xzvf %{SOURCE2} -C .%{gem_instdir}
 pushd .%{gem_instdir}
 %patch1 -p0
 %patch2 -p0
+%patch5 -p2
 popd
 
 pushd .%{gem_dir}
@@ -106,6 +111,9 @@ popd
 
 
 %changelog
+* Wed Jan 09 2013 Vít Ondruch <vondruch at redhat.com> - 1:3.2.8-2
+- Fix for CVE-2013-0156.
+
 * Mon Aug 13 2012 Vít Ondruch <vondruch at redhat.com> - 1:3.2.8-1
 - Update to ActiveSupport 3.2.8.
 


More information about the scm-commits mailing list