CVE-2014-8080: Negación de Servicio (DoS) por Expansión de XML

La expansión de entidades no restringidas puede causar una vulnerabilidad en REXML. A esta vulnerabilidad se le ha asignado el identificador CVE-2014-8080. Nuestra recomendación es que actualices tu versión de Ruby lo antes posible.

Detalles

Cuando se están leyendo nodos de texto en un documento XML, el intérprete REXML puede ser forzado a colocar cadenas muy grandes lo que puede consumir toda la memoria del servidor resultando en un ataque por negación del servicio (DoS).

El código afectado puede verse algo así:

require 'rexml/document'

xml = <<XML
<!DOCTYPE root [
  # vector de expansión ENTITY
]>
<cd></cd>
XML

p REXML::Document.new(xml)

Todos los usuarios que utilizan una versión afectada deberían actualizar cuanto antes o utilizar algunas de las soluciones alternas inmediatamente.

Versiones afectadas

  • Ruby 1.9.x todas las versiones anteriores a Ruby 1.9.3 patchlevel 550
  • Ruby 2.0.x todas las versiones anteriores a Ruby 2.0.0 patchlevel 594
  • Ruby 2.1.x todas las versiones anteriores a Ruby 2.1.4
  • Todo lo anterior a la revisión 48161

Soluciones alternas

Si por alguna razón no puedes actualizar Ruby, utiliza el siguiente parche como solución alterna en versiones de 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

Para versiones de Ruby anteriores a 2.1.0 puedes usar el siguiente parche:

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

Creditos

Agradecemos a Willis Vandevanter por reportar este problema.

Historia

  • Publicado originalmente 2014-10-27 12:00:00 (UTC)