aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/core_ext/hash
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2013-01-05 17:46:26 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2013-01-08 12:42:29 -0800
commit46e0d2397ea10a0bf380926c9fe3cfcf14d5c499 (patch)
tree1001415a74aa4ba81cc8fc305f4cb7a0bc145afc /activesupport/lib/active_support/core_ext/hash
parent8e577fe560d5756fcc67840ba304d79ada6804e4 (diff)
downloadrails-46e0d2397ea10a0bf380926c9fe3cfcf14d5c499.tar.gz
rails-46e0d2397ea10a0bf380926c9fe3cfcf14d5c499.tar.bz2
rails-46e0d2397ea10a0bf380926c9fe3cfcf14d5c499.zip
CVE-2013-0156: Safe XML params parsing. Doesn't allow symbols or yaml.
Diffstat (limited to 'activesupport/lib/active_support/core_ext/hash')
-rw-r--r--activesupport/lib/active_support/core_ext/hash/conversions.rb27
1 files changed, 23 insertions, 4 deletions
diff --git a/activesupport/lib/active_support/core_ext/hash/conversions.rb b/activesupport/lib/active_support/core_ext/hash/conversions.rb
index 6cb7434e5f..8930376ac8 100644
--- a/activesupport/lib/active_support/core_ext/hash/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/hash/conversions.rb
@@ -101,17 +101,33 @@ class Hash
#
# hash = Hash.from_xml(xml)
# # => {"hash"=>{"foo"=>1, "bar"=>2}}
- def from_xml(xml)
- ActiveSupport::XMLConverter.new(xml).to_h
+ #
+ # DisallowedType is raise if the XML contains attributes with <tt>type="yaml"</tt> or
+ # <tt>type="symbol"</tt>. Use <tt>Hash.from_trusted_xml</tt> to parse this XML.
+ def from_xml(xml, disallowed_types = nil)
+ ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h
end
+ # Builds a Hash from XML just like <tt>Hash.from_xml</tt>, but also allows Symbol and YAML.
+ def from_trusted_xml(xml)
+ from_xml xml, []
+ end
end
end
module ActiveSupport
class XMLConverter # :nodoc:
- def initialize(xml)
+ class DisallowedType < StandardError
+ def initialize(type)
+ super "Disallowed type attribute: #{type.inspect}"
+ end
+ end
+
+ DISALLOWED_TYPES = %w(symbol yaml)
+
+ def initialize(xml, disallowed_types = nil)
@xml = normalize_keys(XmlMini.parse(xml))
+ @disallowed_types = disallowed_types || DISALLOWED_TYPES
end
def to_h
@@ -119,7 +135,6 @@ module ActiveSupport
end
private
-
def normalize_keys(params)
case params
when Hash
@@ -145,6 +160,10 @@ module ActiveSupport
end
def process_hash(value)
+ if value.include?('type') && !value['type'].is_a?(Hash) && @disallowed_types.include?(value['type'])
+ raise DisallowedType, value['type']
+ end
+
if become_array?(value)
_, entries = Array.wrap(value.detect { |k,v| not v.is_a?(String) })
if entries.nil? || value['__content__'].try(:empty?)