diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2013-01-08 12:11:18 -0800 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2013-01-08 12:11:18 -0800 |
commit | 88cc1688d0cb828c17706b41a8bd27870f2a2beb (patch) | |
tree | 1001415a74aa4ba81cc8fc305f4cb7a0bc145afc /activesupport/lib | |
parent | f049016cd348627bf8db0d72382d7580bf802a79 (diff) | |
parent | 2ced6f2f8a85957b160710ae5d9fb245a6106550 (diff) | |
download | rails-88cc1688d0cb828c17706b41a8bd27870f2a2beb.tar.gz rails-88cc1688d0cb828c17706b41a8bd27870f2a2beb.tar.bz2 rails-88cc1688d0cb828c17706b41a8bd27870f2a2beb.zip |
Merge branch 'master-sec'
* master-sec:
CVE-2013-0156: Safe XML params parsing. Doesn't allow symbols or yaml.
* Strip nils from collections on JSON and XML posts. [CVE-2013-0155] * dealing with empty hashes. Thanks Damien Mathieu
Diffstat (limited to 'activesupport/lib')
-rw-r--r-- | activesupport/lib/active_support/core_ext/hash/conversions.rb | 27 |
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?) |