CVE-2014-8080: DoS уязвимость в REXML

Неограниченное разворачивание XML-сущности может привести к DoS уязвимости в REXML. Этой уязвимости назначен идентификатор CVE CVE-2014-8080. Мы очень рекомендуем обновить Ruby.

Детали

Во время чтения текстовых нод XML документа, парсер REXML может быть вынужден к резервированию экстремально больших строковых объектов, которые могут растратить всю память машины, вызвав недоступность сервиса (DoS).

Опасный код может выглядеть как-то так:

require 'rexml/document'

xml = <<XML
<!DOCTYPE root [
  # Вектор, расширяющий сущность
]>
<cd></cd>
XML

p REXML::Document.new(xml)

Все пользователи, использующие затронутые релизы, должны либо обновиться, либо использовать один из обходных путей.

Затронутые версии

  • Все версии Ruby 1.9 до Ruby 1.9.3 patchlevel 550
  • Все версии Ruby 2.0 до Ruby 2.0.0 patchlevel 594
  • Все версии Ruby 2.1 до Ruby 2.1.4
  • транк до ревизии 48161

Обходные пути

Если вы не можете обновить Ruby, используйте этот манкипатч как обходной путь:

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

Для версий 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 > 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

Благодарности

Спасибо Willis Vandevanter за сообщение о данной проблеме.

История

  • Оригинал опубликован 2014-10-27 12:00:00 (UTC)