Unrestricted entity expansion can lead to a DoS vulnerability in REXML.
This vulnerability has been assigned the CVE identifier
CVE-2014-8080.
We strongly recommend to upgrade Ruby.

Details

When reading text nodes from an XML document, the REXML parser can be
coerced into allocating extremely large string objects which can
consume all of the memory on a machine, causing a denial of service.

Impacted code will look something like this:

require 'rexml/document'

xml = <<XML
<!DOCTYPE root [
  # ENTITY expansion vector
]>
<cd></cd>
XML

p REXML::Document.new(xml)

All users running an affected release should either upgrade or use one
of the workarounds immediately.

Affected versions

  • All Ruby 1.9 versions prior to Ruby 1.9.3 patchlevel 550
  • All Ruby 2.0 versions prior to Ruby 2.0.0 patchlevel 594
  • All Ruby 2.1 versions prior to Ruby 2.1.4
  • prior to trunk revision 48161

Workarounds

If you cannot upgrade Ruby, use this monkey patch as a workaround on versions of Ruby 2.1.0+:

class REXML::Entity
  def value
      if @value
        matches = @value.scan(PEREFERENCE_RE)
        rv = @value.clone
        if @parent
          sum = 0
          matches.each do |entity_reference|
            entity_value = @parent.entity( entity_reference[0] )
            if sum + entity_value.bytesize > Security.entity_expansion_text_limit
              raise "entity expansion has grown too large"
            else
              sum += entity_value.bytesize
            end
            rv.gsub!( /%#{entity_reference.join};/um, entity_value )
          end
        end
        return rv
      end
      nil
   end
end

For versions of Ruby older than 2.1.0, you can use the following monkey patch:

class REXML::Entity
  def value
      if @value
        matches = @value.scan(PEREFERENCE_RE)
        rv = @value.clone
        if @parent
          sum = 0
          matches.each do |entity_reference|
            entity_value = @parent.entity( entity_reference[0] )
            if sum + entity_value.bytesize > Document.entity_expansion_text_limit
              raise "entity expansion has grown too large"
            else
              sum += entity_value.bytesize
            end
            rv.gsub!( /%#{entity_reference.join};/um, entity_value )
          end
        end
        return rv
      end
      nil
   end
end

Credits

Thanks to Willis Vandevanter for reporting this issue.

History

  • Originally published at 2014-10-27 12:00:00 (UTC)

Posted by zzak on 27 Oct 2014

Read more at the source